python Dis模块进行代码性能分析

​Python代码在执行的时候,会被编译为Python字节码,再由Python虚拟机执行Python字节码。有时候就我们执行python文件的时候会生成一个pyc文件,这个pyc文件即用于存储Python字节码指令,而这些字节码是一种类似于汇编指令的中间语言,但是每个字节码对应的不是机器指令,而是一段C代码。

而Dis模块,就是用于查看这些字节码的运行轨迹,因此我们可以用Dis模块判断两个函数的内存占用谁会更大,谁会更消耗CPU性能,不仅如此,通过指令,我们还可以知道Python中一些内置函数、变量的取值过程、运行逻辑,对于我们代码性能并优化代码很有帮助。

下面将通过两个例子,来介绍Dis模块的使用。

1.为什么下面第一个函数比第二个函数耗得内存更少?

def test1(a):
    if 0 < a and a < 1:
        return 1
    return 0

def test2(a):
    if 0 < a < 1:
        return 1
    return 0

一般人是比较难直接看出来的,但是我们使用Dis模块却能很容易找到答案:

import dis
def test1(a):
    if 0 < a and a < 1:
        return 1
    return 0


def test2(a):
    if 0 < a < 1:
        return 1
    return 0

dis.dis(test1)
print('*'*50)
dis.dis(test2)

结果:

dis结果

Dis的结果其实很容易阅读:

第一列:对应的源代码行数。
第二列:对应的内存字节码的索引位置。
在第一列和第二列之间的 >> 号表示跳转的目标
第三列:内部机器代码的操作。
第四列:指令参数。
第五列:实际参数。

两个函数的dis分析用*号隔开了,大家可以清晰地看到两个函数之间的语句区别。第二个函数的字节码索引最大到了30,而第一个函数的字节码索引最大仅到了22,因此,第一个函数耗得内存比第二个函数少。

而且,在第一列和第二列之间的 >> 号表示跳转的目标,大家可以看第二个函数第四列的 18,表示其跳转到了索引为18的指令,也就是ROT_TWO。第二个函数的跳转也比第一个函数多,这也可能导致其在某种特殊情况下的效率可能会比第一个函数低。

2.为什么Python2中,while True 比 while 1慢?

while 1:
    pass
 
while True:
    pass

可以通过在命令中使用dis进行分析:

可以看到,while 1 在第二行是直接JUMP_ABSOLUTE,因此相比于While True 少了LOAD_NAME 和 POP_JUMP_IF_FALSE。这是因为True在Python2中不是一个关键字,而是一个内置变量,因此每次Python都会用LOAD_NAME去检查(POP_JUMP_IF_FALSE)True的值。这就是为什么While True 比while 1慢的原因。

到了Python3,True变成了关键字,就没有这个问题了:

Python 3 针对 Python 2 做了非常多的替换,这也是为什么它不兼容 Python 2 的原因之一,差别太大了。因此,建议各位初学者直接上手 Python 3 进行学习,而非 Python 2.

希望以上两个Dis模块的使用例子能给大家带来一点灵感,分析一段Python代码的深层次性能问题虽然比较费时费力,但是一旦你分析到了深层次的性能原因,将能累积不少深层次的技术上的知识,写出更漂亮的代码。

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python使用“漫威API”探索漫威宇宙

在看漫威系列电影的时候,你是不是经常会对一些角色感到好奇,想知道每个角色的关联关系和出场的事件,但是却无从下手?

现在,我们有很好的来帮助我们实现这些想法了!Marvel Comics API 允许各地的开发人员访问漫威70年来庞大的漫画信息。接下来就来告诉大家怎么使用这个漫威

1.注册账号获得API访问权限

访问下面的链接注册一个漫威开发者

https://developer.marvel.com/signup

跟着步骤走,接受它的使用条款后就能得到public key(公钥)和 private key(私钥)了:

2.pip安装相应的第三方工具

在pip中输入以下命令安装marvel包(默认你已经安装好了python和pip哦,如果你还没有安装,建议阅读这个教程:python安装)

pip install marvel

这个包是这个漫威API的封装器,里面封装了许多查询工程,方便我们使用,我们不需要理解怎么发送post请求向漫威api调用数据,仅仅使用一个语句,将我们刚刚获得的公钥和私钥传入进去,就可以拿到数据。

公钥秘钥示例

获取所有角色:

import marvel
PUBLIC_KEY = '你的公钥'
PRIVATE_KEY = '你的私钥'
m = marvel.Marvel(PUBLIC_KEY, PRIVATE_KEY)
characters = m.characters
all_characters = characters.all()
print(all_characters)

获取单个角色:

import marvel
PUBLIC_KEY = '你的公钥'
PRIVATE_KEY = '你的私钥'
m = marvel.Marvel(PUBLIC_KEY, PRIVATE_KEY)
characters = m.characters
character = characters.get(1011334)
print(character)

获取一些角色的漫画:

import marvel
PUBLIC_KEY = '你的公钥'
PRIVATE_KEY = '你的私钥'
m = marvel.Marvel(PUBLIC_KEY, PRIVATE_KEY)
characters = m.characters
comics = characters.comics(1011334)
print(comics)

同样,您可以将相同的逻辑应用于不同的对象,例如:

import marvel
PUBLIC_KEY = '你的公钥'
PRIVATE_KEY = '你的私钥'
m = marvel.Marvel(PUBLIC_KEY, PRIVATE_KEY)
stories = m.stories
all_stores = stories.all()
story = stories.get(id)
events = stories.events(id)
print(stories, all_stores, story, events)

最后,每个对象具有的子资源如下:

  • 人物
    • allgetcomicseventsseriesstories
  • 漫画
    • allgetcharacterscreatorseventsstories
  • 创作者
    • allgetcomicseventsseriesstories
  • 活动
    • allgetcharacterscomicscreatorsseriesstories
  • 系列
    • allgetcharacterscomicscreatorseventsstories
  • 故事
    • allgetcharacterscomicscreatorseventsseries

3. 使用API找到雷神出现过的漫画

想要使用API查找灭霸出现过的所有漫画,你就得先知道雷神的角色ID(character ID), 我们通过角色名字得到角色对应的ID:

import marvel
PUBLIC_KEY = '你的公钥'
PRIVATE_KEY = '你的私钥'
m = marvel.Marvel(PUBLIC_KEY, PRIVATE_KEY)
characters = m.characters
def get_hero_id(characters, name):
    all_characters = characters.all(nameStartsWith=name)
    # 根据名字获得角色信息,仅支持英文
    ids = [i['id'] for i in all_characters['data']['results']]
    names = [i['name'] for i in all_characters['data']['results']]
    return ids,names
ids, names = get_hero_id(characters, 'thor')

结果:

(base) ckenddeMacBook-Pro:20190925 ckend$ python 1.py
[1009664, 1017576, 1017106, 1017315, 1017328, 1017302, 1011025, 1010820] ['Thor', 'Thor (Goddess of Thunder)', 'Thor (MAA)', 'Thor (Marvel Heroes)', 'Thor (Marvel War of Heroes)', 'Thor (Marvel: Avengers Alliance)', 'Thor (Ultimate)', 'Thor Girl']

可以看到我们好像得到了不同系列下的雷神,以1009664为例,获得雷神出现过的漫画。

import marvel
PUBLIC_KEY = '你的公钥'
PRIVATE_KEY = '你的私钥'
m = marvel.Marvel(PUBLIC_KEY, PRIVATE_KEY)
characters = m.characters
def get_hero_id(characters, name):
    all_characters = characters.all(nameStartsWith=name)
    # 根据名字获得角色信息,仅支持英文
    ids = [i['id'] for i in all_characters['data']['results']]
    names = [i['name'] for i in all_characters['data']['results']]
    return ids,names
ids, names = get_hero_id(characters, 'thor')
comics = characters.comics(ids[0])
# ids[0]即1009664
print([i['title'] for i in comics['data']['results']])

结果如下:

(base) ckenddeMacBook-Pro:20190925 ckend$ python 1.py
 ['THOR VOL. 2: ROAD TO WAR OF THE REALMS TPB (Trade Paperback)', 'Marvel Masterworks: The Mighty Thor Vol. 18 (Hardcover)', 'King Thor (2019) #1', 'Thor Epic Collection: The Black Galaxy (Trade Paperback)', 'Thor (2018) #16', 'THOR & LOKI: BLOOD BROTHERS GALLERY EDITION HC (Hardcover)', 'Thor Of The Realms (Trade Paperback)', 'War Of The Realms Omega (2019) #1', 'Thor (2018) #15', 'The Unbeatable Squirrel Girl (2015) #46', 'Kirby Is… Mighty! King-Size (Hardcover)', 'Thor (2018) #14', 'War of the Realms (2019) #5', 'MARVEL ACTION CLASSICS: SPIDER-MAN TWO-IN-ONE 1 (2019) #1', 'Thor (2018) #13', 'Moon Girl and Devil Dinosaur (2015) #43', "Decades: Marvel in The '80s - Awesome Evolutions (Trade Paperback)", 'War of the Realms (2019) #3', 'The Art of War of the Realms (Trade Paperback)', 'Mighty Thor 3D (2019) #1']

可以看到,雷神一共在十九部作品里出现过哦。怎么样,是不是特别方便的工具

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

利用Python找出适合你的国考市考公务员岗位

2020年国考已经临近啦,很多小伙伴都在考虑是否要报公务员,但是却不知道适合自己的岗位有什么,今天我们就来利用Python找出适合你的岗位吧!

根据2019年国考全国职位表,可以找到以下的报考限制因素:专业、学历、政治面貌、基层工作年限。该表的下载地址:

由于表格是Excel的xlsx格式,我们需要用到两个包,xlrd和xlwt,使用pip安装即可,如果你还没有安装Python和pip,请看这篇教程:安装Python. 在CMD/TERMINAL输入以下两条命令进行安装:

pip install xlrd
pip install xlwt

假设,假设我们是计算机本科专业,而且没有任何的基层工作经验,以这样的条件筛选表格中适合我们的岗位,(如果你没有耐心看,可以到网站上下载源代码直接用哦):

我们会使用xlrd读取表格,然后用xlwt保存筛选出来的数据,首先是xlrd读取:

data = xlrd.open_workbook(file) 
# 将表格数据读取到data中

然后我们需要一个变量保存筛选数据:

output = xlwt.Workbook(encoding='utf-8')

该表格中还有许多子表格,因此我们需要遍历所有的子表格:

for sheet in data.sheets():
    output_sheet = output.add_sheet(sheet.name)
    # 筛选出来的文件中也添加这些子表格

添加第二行的列信息:

for col in range(sheet.ncols):
    # 添加第二行的列信息
    output_sheet.row(0).write(col, sheet.cell(1,col).value)

接下来是检测文件中的每一行,判断其是否能够满足我们的三个条件:专业、学历、基层限制,由于不好分批展示,这里直接给出全部源代码,大家看注释就应该能看明白了,是一个使用关键词匹配对应表格的方法:

# 完整源代码
# Python实用宝典 2019-09-23
#-*- coding: utf-8 -*-

import xlrd
import xlwt
import re

# 检查是否满足报考条件
def check(row_value, major, edu, year):
    ma = row_value[12]
    # 该岗位所需专业
    ed = row_value[13]
    # 该岗位所需学历
    value = row_value[16]
    # 该岗位所需年限
    if check_major(ma, major) and check_edu(ed, edu) and checkSpecial(value, year):
        return True
    else:
        return False

def check_major(value, major):
    # 检查是否满足专业要求
    pat = re.compile(major)
    if re.search(pat, value):
        return True
    return False

# 检查是否满足学历要求
def check_edu(value, edu):
    pat = re.compile(edu)
    if re.search(pat, value):
        return True
    return False

# 检查基层年限设置
def checkSpecial(value, year):
    pat = re.compile(year)
    if re.search(pat, value):
        return True
    return False

# 根据条件筛选出职位
def filterTitle(file, major, edu, year):
    data = xlrd.open_workbook(file)
    # 将表格数据读取到data中
    output = xlwt.Workbook(encoding='utf-8')
    for sheet in data.sheets():
        output_sheet = output.add_sheet(sheet.name)
        # 筛选出来的文件中也添加这些子表格
        for col in range(sheet.ncols):
            # 添加第二行的列信息
            output_sheet.row(0).write(col, sheet.cell(1,col).value)

        output_row = 1
        for row in range(sheet.nrows):
            # 每一行都检测
            row_value = sheet.row_values(row)

            choosed = check(row_value, major, edu, year)
            # 是否满足三个条件(专业、学历、基层限制)

            if choosed == True:
                # 满足则输出到文件中
                for col in range(sheet.ncols):
                    output_sheet.row(output_row).write(col, sheet.cell(row, col).value)
                output_sheet.flush_row_data()
                output_row += 1
    output.save('output.xls')

if __name__ == '__main__':
    filterTitle('1.xlsx', u'不限|计算机', u'本科', u'无限制')

运行完毕后能在本地找到一个output.xls的文件,里面就是我们筛选出来的所有岗位,可以看到本科计算机能报中央国家党群机关和本级中央行政机关的的岗位比较少,但是国家行政机关省级以下直属岗位非常多,高达901个。事业单位355个。

大家也可以再修改源代码添加城市限制,比如说你希望在广东省工作,那就可以把check函数改成这样:

def check(row_value, major, edu, year, location):
    ma = row_value[12]
    # 该岗位所需专业
    ed = row_value[13]
    # 该岗位所需学历
    value = row_value[16]
    # 该岗位所需年限
    loc= row_value[1]
    # 该岗位位置
    if check_re(ma, major) and check_re(ed, edu) and check_re(value, year) and check_re(loc , location):
        return True
    else:
        return False

然后查看原表格里第二列的值,你会发现大部分国家公务员都是以省为单位的,比如XX广东省科员,那么调用该函数的时候就加一个’广东’参数即可。

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python超简单玩转微信自动回复

今天给大家介绍一个Python模块叫wxpy,它在 itchat 的基础上,通过大量接口优化提升了模块的易用性,并进行丰富的功能扩展

注意:强烈建议仅使用小号运行机器人!从近期 (17年6月下旬) 反馈来看,使用机器人存在一定概率被限制登录的可能性。主要表现为无法登陆 Web 微信 (但不影响手机等其他平台)。

项目主页

https://github.com/youfou/wxpy

用来干啥

一些常见的场景

  • 控制路由器、智能家居等具有开放接口的玩意儿
  • 运行脚本时自动把日志发送到你的微信
  • 加群主为好友,自动拉进群中
  • 跨号或跨群转发消息
  • 自动陪人聊天
  • 逗人玩

总而言之,可用来实现各种微信个人号的自动化操作

轻松安装

wxpy 支持 Python 3.4-3.6,以及 2.7 版本,假设你已经完成了Python的基本安装,如果没有的话请见这篇教程:Python 安装教程

  1. 从 PYPI 官方源下载安装 (在国内可能比较慢或不稳定):
pip install -U wxpy
  1. 从豆瓣 PYPI 镜像源下载安装 (推荐国内用户选用):
pip install -U wxpy -i "https://pypi.doubanio.com/simple/"

超简单上手

登陆微信:

# 导入模块
from wxpy import *
# 初始化机器人,扫码登陆
bot = Bot()

找到好友:

# 搜索名称含有 "游否" 的男性深圳好友
my_friend = bot.friends().search('游否', sex=MALE, city="深圳")[0]

发送消息:

# 发送文本给好友
my_friend.send('Hello WeChat!')
# 发送图片
my_friend.send_image('my_picture.jpg')

自动响应各类消息:

# 打印来自其他好友、群聊和公众号的消息
@bot.register()
def print_others(msg):
    print(msg)

# 回复 my_friend 的消息 (优先匹配后注册的函数!)
@bot.register(my_friend)
def reply_my_friend(msg):
    return 'received: {} ({})'.format(msg.text, msg.type)

# 自动接受新的好友请求
@bot.register(msg_types=FRIENDS)
def auto_accept_friends(msg):
    # 接受好友请求
    new_friend = msg.card.accept()
    # 向新的好友发送消息
    new_friend.send('哈哈,我自动接受了你的好友请求')

保持登陆/运行:

# 进入 Python 命令行、让程序保持运行
embed()

# 或者仅仅堵塞线程
# bot.join()

其他

强大的wxpy模块还有其他功能哦,比如:

  1. 发送文本、图片、视频、文件
  2. 通过关键词或用户属性搜索 好友、群聊、群成员等
  3. 获取好友/群成员的昵称、备注、性别、地区等信息
  4. 加好友,建群,邀请入群,移出群

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 超简单爬取微博热搜榜数据

微博的热搜榜对于研究大众的流量有非常大的价值。今天的教程就来说说如何爬取微博的热搜榜。 热搜榜的链接是:

https://s.weibo.com/top/summary/

用浏览器浏览,发现在不登录的情况下也可以正常查看,那就简单多了。使用开发者工具(F12)查看页面逻辑,并拿到每条热搜的CSS位置,方法如下:

按照这个方法,拿到这个td标签的selector是:
pl_top_realtimehot > table > tbody > tr:nth-child(3) > td.td-02

其中nth-child(3)指的是第三个tr标签,因为这条热搜是在第三名的位置上,但是我们要爬的是所有热搜,因此:nth-child(3)可以去掉。

还要注意的是 pl_top_realtimehot 是该标签的id,id前需要加#号,最后变成:
#pl_top_realtimehot > table > tbody > tr > td.td-02

你可以自定义你想要爬的信息,这里我需要的信息是:热搜的链接及标题、热搜的热度。它们分别对应的CSS选择器是:

链接及标题:#pl_top_realtimehot > table > tbody > tr > td.td-02 > a
热度:#pl_top_realtimehot > table > tbody > tr > td.td-02 > span

值得注意的是链接及标题是在同一个地方,链接在a标签的href属性里,标题在a的文本中,用beautifulsoup有办法可以都拿到,请看后文代码。

现在这些信息的位置我们都知道了,接下来可以开始编写程序。默认你已经安装好了python,并能使用cmd的pip,如果没有的话请见这篇教程:python安装。需要用到的python的包有:

BeautifulSoup4 安装指令:

pip install beautifulsoup4

lxml解析器安装指令:

pip install lxml

lxml是python中的一个包,这个包中包含了将html文本转成xml对象的工具,可以让我们定位标签的位置。而能用来识别xml对象中这些标签的位置的包就是 Beautifulsoup4.

编写代码:

# https://s.weibo.com/top/summary/
import requests
from bs4 import BeautifulSoup

if __name__ == "__main__":
    news = []
    # 新建数组存放热搜榜
    hot_url = 'https://s.weibo.com/top/summary/'
    # 热搜榜链接
    r = requests.get(hot_url)
    # 向链接发送get请求获得页面
    soup = BeautifulSoup(r.text, 'lxml')
    # 解析页面

    urls_titles = soup.select('#pl_top_realtimehot > table > tbody > tr > td.td-02 > a')
    hotness = soup.select('#pl_top_realtimehot > table > tbody > tr > td.td-02 > span')

    for i in range(len(urls_titles)-1):
        hot_news = {}
        # 将信息保存到字典中
        hot_news['title'] = urls_titles[i+1].get_text()
        # get_text()获得a标签的文本
        hot_news['url'] = "https://s.weibo.com"+urls_titles[i]['href']
        # ['href']获得a标签的链接,并补全前缀
        hot_news['hotness'] = hotness[i].get_text()
        # 获得热度文本
        news.append(hot_news) 
        # 字典追加到数组中 
    
    print(news)

代码说明请看注释,不过这样做,我们仅仅是将结果保存到数组中,如下所示,其实不易观看,我们下面将其保存为csv文件。

Python 热搜榜爬虫
    import datetime
    today = datetime.date.today()
    f = open('./热搜榜-%s.csv'%(today), 'w', encoding='utf-8')
    for i in news:
        f.write(i['title'] + ',' + i['url'] + ','+ i['hotness'] + '\n')

效果如下,怎么样,是不是好看很多:

Python 微博热搜榜爬虫

完整代码如下:

# https://s.weibo.com/top/summary/
import requests
from bs4 import BeautifulSoup

if __name__ == "__main__":
    news = []
    # 新建数组存放热搜榜
    hot_url = 'https://s.weibo.com/top/summary/'
    # 热搜榜链接
    r = requests.get(hot_url)
    # 向链接发送get请求获得页面
    soup = BeautifulSoup(r.text, 'lxml')
    # 解析页面

    urls_titles = soup.select('#pl_top_realtimehot > table > tbody > tr > td.td-02 > a')
    hotness = soup.select('#pl_top_realtimehot > table > tbody > tr > td.td-02 > span')

    for i in range(len(urls_titles)-1):
        hot_news = {}
        # 将信息保存到字典中
        hot_news['title'] = urls_titles[i+1].get_text()
        # get_text()获得a标签的文本
        hot_news['url'] = "https://s.weibo.com"+urls_titles[i]['href']
        # ['href']获得a标签的链接,并补全前缀
        hot_news['hotness'] = hotness[i].get_text()
        # 获得热度文本
        news.append(hot_news)
        # 字典追加到数组中
    
    print(news)

    import datetime
    today = datetime.date.today()
    f = open('./热搜榜-%s.csv'%(today), 'w', encoding='utf-8')
    for i in news:
        f.write(i['title'] + ',' + i['url'] + ','+ i['hotness'] + '\n')

​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python生成器不该这么用

最近在知乎上有人误解了Python生成器的使用,在这里我们来统一探讨下它这么用对不对。

举一个例子,编写一个函数计算一串数字里所有偶数的个数,其实是很简单的问题,但是有些人是用生成器这么写的:

In [66]: def f1(x):
   ....:     return sum(c in '02468' for c in str(x))
   ....: 
In [68]: x = int('1234567890'*50)
In [69]: %timeit f1(x)
10000 loops, best of 5: 52.2 µs per loop

生成器这么用其实是速度最慢的一种做法,花费了52微秒。我们来看看如果我改成列表解析式会怎么样:

In [67]: def f2(x):
  ....:     return sum([c in '02468' for c in str(x)])
  ....:  
In [70]: %timeit f2(x)
10000 loops, best of 5: 40.5 µs per loop 

你看,这个加速非常地明显,仅花费了40.5微秒

而且还能进一步改进, 如果我们改变之前定义的f2,让它在列表解析式后判断数字是否为偶数,是偶数才会成为最终生成的列表中的一员,这样有另一个加速:

In [71]: def f3(x):
   ....:     return sum([True for c in str(x) if c in '02468'])
   ....: 
In [72]: %timeit f3(x)
10000 loops, best of 5: 34.9 µs per loop


34.9微秒,Perfect! 不仅如此,还能继续加速!sum对于整数有一个快速路径,但是这个快速路径只激活类型为int的变量. bool不行,因此我们把True改成1,能再加一次速!

In [73]: def f4(x):
   ....:     return sum([1 for c in str(x) if c in '02468'])
   ....: 
In [74]: %timeit f4(x)
10000 loops, best of 5: 33.3 µs per loop

​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典


Python里Yield关键词的作用

要理解yield的作用,您必须理解生成器是什么。在理解生成器之前,必须先理解迭代器。

迭代器

当您创建一个列表时,您可以逐个读取它的项。逐项读取其项称为迭代:

>>> mylist = [1, 2, 3]
>>> for i in mylist:
...    print(i)
1
2
3

mylist是一个可迭代的对象。当你使用列表解析式时,你创建了一个列表,因此也是一个迭代器:

>>> mylist = [x*x for x in range(3)]
>>> for i in mylist:
...    print(i)
0
1
4

所有你可以用”for… in ….”都是迭代器,包括列表、字符串、文件…等等。

这些迭代器非常方便,因为您可以随心所欲地读取它们,但是您将所有的值都存储在内存中,当您有很多值时,这就非常浪费内存了。

生成器

生成器是迭代器,这种迭代器只能迭代一次。生成器不会将所有值都存储在内存中,它们会动态生成这些值:

>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator:
...    print(i)
0
1
4

它和列表解析式是类似的,只是用()代替了[]。但是,您不能在mygenerator中对i执行第二次,因为生成器只能使用一次:它print(0),然后忘记它,print(1),最后是4。

Yield

yield是一个与return类似的关键字,只是函数将返回一个生成器

>>> def createGenerator():
...    mylist = range(3)
...    for i in mylist:
...        yield i*i
...
>>> mygenerator = createGenerator() # create a generator
>>> print(mygenerator) # mygenerator is an object!
 <generator object createGenerator at 0xb7555c34>
>>> for i in mygenerator:
...     print(i)
0
1
4

您需要知道的是函数将返回一组只需要读取一次的值,将这个特性理解清楚,用对地方将极大地提高性能,下次我们将介绍在什么时候该用它。

要掌握yield,您必须了解,在调用函数时,在函数体中编写的代码不会运行。函数只返回生成器对象,这有点棘手:-)

然后,您的代码将从每次使用生成器时停止的地方继续。

现在是最难的部分:

for函数第一次调用从函数创建的生成器对象时,它将从头运行函数中的代码,直到达到yield,然后返回循环的第一个值。然后,彼此调用将再次运行您在函数中编写的循环,并返回下一个值,直到没有要返回的值为止,就如我们上面的例子所示。

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

知乎上这么多推崇学 Python的,如果学完这一套找不到工作怎么办?

Python 的岗位本来就比较少,而且大部分都对经验要求比较高,没有什么初级岗位啊。尤其是非北上广城市,职位数量少,要求反而比一线城市更高,我个人对这些人转行不看好,欢迎指正。

答案:

这个问题,确实很有价值。

毕竟,掌握一门技能,是需要花成本的。决策之前,做个前景判断,衡量投入产出比,是应该的。

然而,一旦深入思考,你可能自己就会对学 Python 的价值,颇为疑虑。

因为大部分人看待这个问题,是在判断 Python 学过后,能否提升自己的竞争力。

国人常说的俗谚,有一句“一招鲜,吃遍天”。也就是掌握了某种供不应求的技能,于是可以坐享这种技能带来的益处与红利。

你可以暂停阅读20秒钟,在头脑里,自行匹配满足上述条件的相应技能,或是代表该技能的证书。

想好后,咱们继续。

这样的技能,确实是存在。但是,要达到“吃遍天”的效果,需要你衡量市场上的供求关系。

我们都知道,近几年市场对 Python 的需求确实很高。许多岗位招聘条件里面,都有 Python 这一项。

然而,供求关系的另一方,也就是供给,情况如何呢?

很不容乐观。

我不是说供给太少,而是太多了些。

别忘了, Python 最大的特点,就是简单易学。

因此,没有门槛,没有护城河,连上小学的孩子,课本上都要教 Python 了

需求再大,如果供给是这样的,价格也很难上去。

所以,如果你的打算,是学好 Python 以后,直接用它变现,那你一定要三思而后行。

这是不是说,你不该学 Python 呢?

恰恰相反,你真的应该学 Python 。

你可能会疑惑:老师,你这不是前后矛盾吗?

不是。

Python 要学,但这项技能,真的不是这么应用的。

连接

Python 无门槛,这么简单,学会了也毫不稀奇,那学它还有什么用?

用处大了。

因为它可以让你和一张巨大的协作网络连接起来。这张网络的溢出效应,对你来说益处可谓巨大。

举个例子。

机器学习听说过吧?最近很火的。

从前人们做机器学习,用的工具叫做 Matlab 。

直到6、7年前,当 Andrew Ng 制作后来成为经典的《机器学习》课程时,用的工具还是 Matlab 。

当然,因为当时 Matlab 很贵,所以 Andrew Ng 鼓励大家用 Octave (一种 Matlab 的开源实现版本)替代。

我学这门课程的时候,很痛苦。其中最重要的原因,就是 Matlab / Octave 的使用。

这是当时做的第 8 次作业,你看看为了做个协同过滤(Collaborative Filtering),需要多少个文件。

随便打开一个代码文件,是这样的:

结果是,大部分学员,根本就不知道,该如何完整撰写一个协同过滤算法的程序。大家只能满足于课程的要求,即在每个文件指定的位置上,做完形填空。

因此,那时候你要是打算使用机器学习,就必须要抱着一本 Matlab 的书啃下来。因为只有明白了它怎么用,你才真正能壮起胆子,尝试从头到尾,去实践自己从 MOOC 学来的机器学习技能。

然而,短短几年之后,事情就完全变了。

2017年,Andrew Ng 的 Coursera 课程《深度学习》推出,这次,他再也不提什么 Matlab 了,从头到尾都是 Python 。

Andrew 教起来轻松,大家学习起来开心。而且更妙的是,因为 Python 简单易懂,因此全部示例代码,你可以很容易看明白,并且知道当应用于自己的实际项目时,修改哪些部分,就可以复用。

其他基于 Python 的机器学习课程,也像雨后春笋一般遍地开花。

例如在 fast.ai 的课程里,实现同样的协同过滤功能,你再也不用写那一堆 Matlab 文件和函数了。

你需要的,仅是以下这几行代码:

from fastai.collab import *
path = untar_data(URLs.ML_SAMPLE)
ratings = pd.read_csv(path/'ratings.csv')
ratings.head()
data = CollabDataBunch.from_df(ratings)
learn = collab_learner(data, n_factors=50, y_range=(0.,5.))
learn.fit_one_cycle(5, 5e-3, wd=0.1)

好了,搞定。

Python 没有门槛。但是通过掌握它,你可以用更短的时间,更高的效率学习和掌握机器学习,甚至是深度学习的技能。

注意,能以这么短短几行代码搞定问题,不是因为你学了 Python ,所以技能大涨。

那是因为这个巨大协作网络中开发框架的人,“刚巧”也是用 Python 来封装细节。你们在说同样的语言,因此你可以把他们的研究成果,“拿来”使用。

越来越多的高手都使用 Python 来编写框架、制作工具,因此会吸引更多人来用。

越来越多的人习惯用 Python 来完成某项功能,那么开发功能的人也被绑定在这个路径上,只能选择用 Python 来开发。

这样的一个正反馈循环,就像在滚雪球。

你可能很为那些好不容易掌握用 Matlab 做机器学习的人鸣不平,似乎他们才是会真功夫的人。而学了 Python 的人,都有作弊之嫌。

才不会。能掌握 Matlab 的人,都可以很容易学会 Python ,他们也可以立即加入这张协作网络,享受这种便利。

好玩儿的是,2017年, Matlab 开源了一本机器学习教材,供大家免费下载。

你猜群众的反馈是啥?

排在第一位的,是这样:

为什么?人家好心好意给你书,你为何不要?

看这个曲线。

这是 Google 趋势上面,用“matlab machine learning”和“python machine learning”分别检索,得来的结果。

可以看到,如果今天你选择用 Matlab 来做机器学习,你的协作网络,和 Python 比起来,小得可以忽略不计。

这网络里面,包括为你打造工具的高手们,为你提供教程的人,也包括你潜在的合作伙伴……

你是希望自己的网络大一些,还是小一些呢?

方法

了解了 Python 的特点,你也就大略知道,该怎么去学它了。

我见过不少初学者,深吸一口气,摆开阵仗,恨不得投入一年的时间,“系统”掌握它。

其实没必要这么如临大敌。

如果教材编写者假设,儿童都能在一个学期内学会 Python ,你一个受过高等教育的成人,学起来应该更轻松才对。

其实你看现在那些好的 MOOC 里面(主题包括但不限于数据分析、数据可视化、机器学习、深度学习……), Python 学习大概是怎么做的。

他们会说,这门课咱们要用到 Python ,所以,本课程的第3章,是 Python 的学习。

对,Python ,这门编程语言,只占了一章的篇幅。

学一章,就掌握 Python 了?

看你怎么定义“掌握”了。

要是说你对 Python 的知识全面系统获取到了,那简直是在骗人。

就像你学龄前的时候,基本上也算能用中文对话了,对吧?

但是,你知道“回”字有四种写法吗?

人家授课者的意思是,学了这些 Python 知识,在他这门课就算够用了。

后面如果出现没有涉及过的函数或者方法,给你简单说几句,就可以继续学习了。

你千万不要用背单词的方式来学 Python ,那效率会低得惨不忍睹。

说句题外话,即便你用背单词的方式来学英语,我也不推荐。

你学 Python ,就应该是快速掌握一个最小核心技能集,例如知道怎么赋值、怎么判断、怎么循环,然后会自定义一个函数,可以输入输出东西……好了,可以上路了。

因为大部分的工作中,主要就用上述这些功能。遇到不明白的,直接查文档。Python 的文档,只要你不嫌弃它太详细就好。

查文档搞不定的问题,也没关系,反正这门语言,世界上有数不清的人都会,论坛上发帖问呗。这是给别人提供实现自我价值的机会。说实话,这机会不好碰到,说不定有人甚至会感谢你的提问呢。

你看,这样一来,你的技能来自于对真实问题的挑战,这样学起来,你的动力更足,学会之后你的满足感更强。而且,你的记忆,会更加深刻。

资源

学习 Python 的资源,我在《如何高效学Python?》一文中已经为你详细做过介绍和推荐,这里就不再赘述了。

此处只介绍我最近发现的2个新资源,都是免费的。

一个是 IBM 提供的系列课程。其中的 Python 基础课,叫做 Python for Data Science ,编号 PY0101EN 。网址在这里

除了免费、自主决定学习进度外,这门课的好处在于提供在线的 Jupyter Lab 编程环境。初学者最容易遇到的环境配置陷阱,在这里统统不存在。

如果你更喜欢读书的方式来学习,这里有一张交互式的数据科学教材汇总图。

你可以着重看其中的 Python 部分。

注意这张学习路线交互图是免费的。里面介绍的书,有的免费,有的收费。你可以酌情选择。

小结

通过阅读本文,希望你能掌握以下知识点:

首先,Python 本身不是什么独门绝艺,不要被人忽悠,以为学了 Python 就能……;
其次,Python 是你连接到一个巨大协作网络的桥梁,网的正外部性会让你充分受益。偏偏这桥梁还没有守卫,因此你,即便是个听到技术就头痛的文科生,也可以轻松进入;
第三,学习 Python ,不要追求系统,更不要舍本逐末去死记硬背知识。采用“快速掌握核心知识+解决实际问题中练习补充”的方式,更为有效;
第四,推荐了一些优质免费资源给你,希望能有帮助。

综上,学 Python ,确实有助于提升你的竞争力。但是再强调一遍,那竞争力,并非来自 Python 本身。

祝学习愉快!

喜欢请点赞和打赏。还可以微信关注和置顶我的公众号“玉树芝兰”(nkwangshuyi)

如果你对 Python 与数据科学感兴趣,不妨阅读我的系列教程索引贴《如何高效入门数据科学?》,里面还有更多的有趣问题及解法。


作者:gashero
链接:https://www.zhihu.com/question/60787862/answer/329788391
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

举几个数字,略残酷,希望不要抹杀了大家的积极性。

中国现存程序员约185万人,2017年高等教育毕业人数795万人。截止2017年末,中国高等教育人口总数约1.85亿。

http://www.sohu.com/a/165615021_475887

http://study.ccln.gov.cn/fenke/shehuixue/shjpwz/shfcyld/381468.shtml

虽然程序员中有极少数没有接受过高等教育,但至少主流是受过高等教育的。这个数字至少意味着每年广义电子信息类毕业生总量是超过程序员历史存量的,或者说,即便是学了未来可能做程序员的专业,大部分人也没法做程序员。

好消息是相对其他专业,程序员的薪资较高,没有过多对历史身份的限制,即不管你之前学啥专业,在哪个学校毕业,只要能力符合要求,就可以成为程序员。

成为程序员的最大门槛,就是脑力,我没有用智力这个词,主要是因为希望脑力这个词也包含了长时间大强度用脑的意思,而不仅仅是灵光一现的智力。

很多人推荐大家从Python入门进入程序员,除了如上薪资高,没身份门槛外的优势外。也是希望能够帮助那些有编程天赋的人发现自己的天赋,并成为程序员。

但这种建议并不能确保你学了Python就能成为程序员,可以说绝大部分人学了以后肯定做不了程序员。

假设程序员的平均职业生命是10年,有些人会做的更长,也有很多人早早转行去创业,做销售,做产品、被辞退之类。那么每年会有18.5万职位空缺出来,加上新增职位,可以假设为每年新产生程序员职位约20万。那么新人就是要抢这大约20万个程序员职位。相对毕业人数,大约是2.5%的人可以成为程序员。

所以,做个比喻,不从悬崖上跳下去,你怎么知道你不是鹰呢?不试试Python,你怎么知道自己不适合编程呢?相对于以往死气沉沉熬资历的时代,有个机会能挑战一下自己已经很美好了。

学python都用来干嘛?

我最近学python,不过不知道怎么练习,不知道用来写什么。大家都用来干嘛的?都说说python可以用来写什么好玩的东东。

答案

能写的东西可太多了,日常生活的有这么些有趣的教程

比如哄哄女朋友:Python导出微信聊天记录并生成词云

向手机发送通知:教你如何使用Python向手机发送通知(IFTTT)

文献搜索工具你不得不知道的python超级文献搜索工具

制作日历Excel+Python=精美壁纸日历 任意DIY

如果你想成为超级极客,可以看看这些文章:

树莓派+智能音箱Python声控普通风扇Python声控开机

树莓派+摄像头:Python人脸识别开机

Python 深度学习图像风格迁移

零基础学接私活,Python还是Java。学哪个语言比较好?

零基础自学编程,Python还是Java,目的是接私活。请问学哪个语言比较好?

答案:

零基础推荐学Python,那么多计算机领域以外的人都用Python不是没有原因的:

  1. 开发速度快,各种开源任你用
  2. 开源社区强大,想做什么都找得到代码
  3. 简单易学,代码易懂

不过私活的方向大概是三条:1.做网站、2.爬虫、3.数据挖掘。

往哪一条线路走深一点其实都能赚钱。