高级特性
列表生成式¶
当要生成list时, 可以用list(range(1,11)), 但如果生成[1x1, 2x2,..., 10x10], 一般用循环
1 | L=[] |
可以用一行语句替换循环生成上面的list [x * x for x in range(1, 11)]
同时, for循环后面还可以加上if判断 [x * x for x in range(1, 11) if x % 2 == 0]
还可以循环嵌套
for…if/if…else…for…的区别¶
- 在使用列表生成式时, 如果在
for...后使用if...来限定, 则不加else语句, 因为这个if是一个筛选条件 - 如果在列表生成式中, 先用
if..., 则必须加else..., 因为这表示一个条件语句, 不论前面的表达式是否需要迭代
生成器¶
通过列表生成式, 我们可以直接创建一个列表; 但受到内存限制, 列表容量有限, 而且我们可能只访问前面的几个元素, 那后面绝大多数的元素白白浪费
在这种情况下, 我们可以用生成器
generator, 在循环的过程中不断推算出后续元素, 而不必创建完整的列表
生成方法¶
-
将一个列表生成式的
[]改成(), 将创建了一个generator1
2
3L = (x * x for i in range(10))
L
<generator object <genexpr> at 0x1022ef630> -
在一个函数中包含
yield关键字如: 斐波那契数列的实现1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# 普通函数
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n += 1
return 'done'
# 生成器
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n += 1
return 'done'
使用方法¶
- 可以通过
next()函数获得生成器的下一个返回值(注: 因为生成器保存的是算法, 所以每次调用next()就计算出下一个值, 直到计算到最后一个元素后, 再使用就抛出StopIteration错误) - 使用
for循环, 因为生成器也是可迭代对象, 同时此时也不要关心StopIteration错误
理解难点¶
将一般的列表生成式变为生成器的执行流程较好理解, 但将函数变为生成器后的执行流程理解比较困难
函数是顺序执行, 遇到return语句或最后一行函数语句返回, 而变成生成器后, 函数在每次调用next()时执行, 遇到yield返回, 再次执行时从上回返回的yield语句处继续执行, 直到遇到return语句或函数体的最后一条语句
在使用for循环迭代生成器时, 无法获得return的返回值; 如果想拿到, 必须捕获StopIteration错误, 返回值包含在StopItreation的value中
迭代器¶
可以直接作用于for循环的数据类型有以下几种:
- 集合数据类型, 如:
list,tuple,dict,set,str等 generator, 包括生成器和带yield的generator function
定义¶
这些可以直接作用于for循环的对象统称为可迭代对象Iterable, 可使用isinstance()判断
而generator不仅可以作用于for循环, 还可以被next()不断调用并返回下一个值, 而可以被next()调用并不断返回下一个值的对象称为迭代器Iterator
也即, **可迭代对象Iterable包括迭代器Iterator及不属于迭代器的list, dict, str等可迭代对象; 而迭代器Iterator包括生成器generator**及由iter()函数转化后的list, dict, str等
原因¶
Iterator对象表示一个数据流, 其可以被next()函数调用并不断返回下一个数据, 直到没有数据抛出StopIteration错误; 可以把这个数据流看作一个有序序列, 但我们却不能提前知道序列的长度, 所以Iterator的计算是惰性的, 只有在需要返回下一个数据时它才会计算, 因此它可以表示一个无限大的数据流, 如: 全体自然数
for循环的实质¶
1 | for x in [1, 2, 3, 4, 5]: |


