列表生成式
顾名思义,列表生成式是用来专门生成list的表达式,是一小段很精简的代码。基本的语法是: [变量表达式 for 变量 in 表达式],请看下面的例子。
a = [x ** 2 for x in range(1, 10)]
b = [x * x for x in range(1, 11) if x % 2 == 0]
print(type(a))
print(type(b))
print(a)
print(b)
结果:
<class 'list'>
<class 'list'>
[1, 4, 9, 16, 25, 36, 49, 64, 81]
[4, 16, 36, 64, 100]
列表生成式总是用十分精简的代码就能返回一个完整的列表,方便了开发。但是在开发过程中往往要注意生成的list是否会占用较多的内存,如果占用的内存较多而且list的生命周期又很长的话,就要考虑生成器了。
生成器
把列表生成式中的[]换成()得到的就是一个生成器。生成器相对于列表生成式的优点就是即能获得列表中一样的数据占用的内存也很少。
c = (x ** 2 for x in range(1, 10))
d = (x * x for x in range(1, 11) if x % 2 == 0)
print(type(c))
print(type(d))
print(c)
print(d)
结果:
<class 'generator'>
<class 'generator'>
<generator object <genexpr> at 0x03A961F0>
<generator object <genexpr> at 0x03A96230>
由于返回的是一个生成器对象,又没有重写它的__str__方法,因此用print直接打印是无法获取其中的内容的。
生成器的遍历
使用next方法或者for可以遍历生成器对象。next()方法在没有元素可以调用的时候,会返回 StopIteration 的错误 ,因此实际使用过程中常用for来获取内容。
c = (x ** 2 for x in range(1, 10))
d = (x * x for x in range(1, 11) if x % 2 == 0)
for i in c:
print(i)
print('====================')
print(next(d))
print(next(d))
print(next(d))
print(next(d))
print(next(d))
结果:
1
4
9
16
25
36
49
64
81
====================
4
16
36
64
100
函数中带yield 关键字
如果一个函数包含了yield 关键字,那么该函数就不再是普通的函数,而是一个生成器。
包含 yield 语句的函数会被特定的编译成生成器。可以把生成器理解为迭代器。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次执行 next()方法时从当前位置继续运行。
for i in range(5):
print()
def fib(n):
sum = 0
i = 0
while (i<n):
sum = sum + i
i += 1
yield(sum)
#print(sum) 此处将print(sum)换成yield
结果:
<class 'generator'>
0
1
3
6
10
15
21
28
36
45
迭代器
- 迭代器是访问集合元素的一种方式
- 迭代器有两个方法,生成迭代器 iter(),返回迭代器的下一个项目 next()
- 字符串、列表、元组、字典、集合 都可以用于创建迭代器
迭代器 和可迭代对象 的区别在于:
可以直接作用于for循环的对象统称为可迭代对象:list、tuple、dict、set、str等。
可以被next
函数调用并不断返回下一个值的对象称为迭代器:Iterator
#list、dict、str等数据类型不是Iterator,但是可以通过 iter() 来创建迭代器
str = 'hello world'
it = iter(str) # 创建迭代器对象
print (next(it)) # 输出迭代器的下一个元素
print (next(it))
结果:
h
e