迭代
如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。
在Python中,迭代是通过for … in来完成的
使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行,而我们不太关心该对象究竟是list还是其他数据类型。
列表生成式
列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
- 语法格式:
基础语法格式
[exp for iter_var in iterable]
实例:
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
工作过程:
迭代iterable中的每个元素;
每次迭代都先把结果赋值给iter_var,然后通过exp得到一个新的计算值;
最后把所有通过exp得到的计算值以一个新列表的形式返回。
相当于这样的过程:
L = []
for iter_var in iterable:
L.append(exp)
带过滤功能语法格式
[exp for iter_var in iterable if_exp]
工作过程:
迭代iterable中的每个元素,每次迭代都先判断if_exp表达式结果为真,如果为真则进行下一步,如果为假则进行下一次迭代;
把迭代结果赋值给iter_var,然后通过exp得到一个新的计算值;
最后把所有通过exp得到的计算值以一个新列表的形式返回。
相当于这样的过程:
L = []
for iter_var in iterable:
if_exp:
L.append(exp)
循环嵌套语法格式
[exp for iter_var_A in iterable_A for iter_var_B in iterable_B]
工作过程:
每迭代iterable_A中的一个元素,就把ierable_B中的所有元素都迭代一遍。
相当于这样的过程:
L = []
for iter_var_A in iterable_A:
for iter_var_B in iterable_B:
L.append(exp)
九九乘法表应用:
print('\n'.join([' '.join(["%d*%d=%2s" % (y, x, x*y) for y in range(1, x+1)]) for x in range(1, 10)]))
等同于
Lx = []
for x in range(1, 10):
Ly = []
for y in range(1, x + 1):
Ly.append("%d*%d=%2s" % (y, x, x*y))
a = " ".join(Ly)
Lx.append(a)
print('\n'.join(Lx))
生成器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。
在Python中,这种一边循环一边计算的机制,称为生成器:generator。
要创建一个generator,有很多种方法。
第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
第二种方法:yield
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
这就是定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:
>>> f = fib(6)
>>> f
<generator object fib at 0x104feaaa0>
要想获取内容需要使用for in进行迭代
小结
generator是非常强大的工具,在Python中,可以简单地把列表生成式改成generator,也可以通过函数实现复杂逻辑的generator。
要理解generator的工作原理,它是在for循环的过程中不断计算出下一个元素,并在适当的条件结束for循环。对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令,for循环随之结束。
请注意区分普通函数和generator函数,普通函数调用直接返回结果:
>>> r = abs(6)
>>> r
6
generator函数的“调用”实际返回一个generator对象:
>>> g = fib(6)
>>> g
<generator object fib at 0x1022ef948>
迭代:
任何可迭代对象都可以作用于for循环,包括我们自定义的数据类型,只要符合迭代条件,就可以使用for循环。
列表生成式:
运用列表生成式,可以快速生成list,可以通过一个list推导出另一个list,而代码却十分简洁。
生成器:
一边循环一边计算的机制,generator
迭代器:
可以被next()函数调用并不断返回下一个值的对象:Iterator
生成器能否只输出想要的结果,而不是生成一个list
仅仅是存储时节省空间,但在输出为list时,并没有显示出优势,输出的时候还是占内存空间