- 一、列表解析List Comprehension
- 语法:[返回值 for i in 可迭代对象 if 条件]
- 使用中括号[],内部是for循环,if条件判断语句是可选
- 列表解析式返回一个新的列表
- 列表解析式是一种语法糖,编译器会优化,不会因为简写而影响效率,反而会提高效率
- 简化了代码,可读性增强
- 举例:
1、生成一个列表,元素0-9,对每个元素自增1后求平方返回新列表
>>> l1 = list(range(10))
>>> l2 = [(i+1)**2 for i in l1]
>>> l2
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
2、求10以内的偶数
>>> even = [x for x in range(10) if x%2==0]
>>> print(even)
[0, 2, 4, 6, 8]
•3、列表e返回都为None
e = [print(i) for i in range(10)]
4、20以内,既能被2整除又能被3整除的数
>>> e = [i for i in range(20) if i%2==0 and i%3==0]
>>> e
[0, 6, 12, 18]
二、列表解析进阶
- 语法:[返回值 for i in iterable1 for j in iterable2]
- 等价于:
- ret=[]
for i in iterable1:
for j in iterable2:
ret.append(返回值) - 举例:
[(x,y) for x in 'abcde' for y in range(3)]
>>> [(x,y) for x in 'abcde' for y in range(3)]
[('a', 0), ('a', 1), ('a', 2), ('b', 0), ('b', 1), ('b', 2), ('c', 0), ('c', 1), ('c', 2), ('d', 0),
('d', 1), ('d', 2), ('e', 0), ('e', 1), ('e', 2)]
>>> [(i,j) for i in range(7) if i>4 for j in range(20,25) if j>23]
[(5, 24), (6, 24)]
三、生成器表达式
1、语法:
- (返回值 for i in 可迭代对象 if条件)
- 生成器是可迭代对象,迭代器
- 列表解析式中的中括号换成小括号就是生成器表达式,返回一个生成器
2、生成器和列表解析式的区别
- 生成器表达式是按需计算(或称为延迟计算),需要的时候才计算值
- 列表解析式立即返回所有值
- 举例:
>>> g = ("{:0}".format(i) for i in range(1,11))
>>> next(g)
'1'
>>> for x in g:
print(x)
四、生成器generator
- 生成器指的是生成器对象,可以由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,调用这个函数得到一个生成器对象
1、生成器函数
- 函数体中包含yield语句的函数,返回生成器对象
- 包含yield语句的生成器函数生成 生成器对象的时候,生成器函数的函数体不会立即执行
- next(generator)会从函数的当前位置向后执行到之后的碰到的第一个yield语句,会弹出值并暂停函数
- 再次调用next函数,接着处理下一条yield语句,没有多余的yield语句被执行就会抛异常
- 生成器对象是一个可迭代对象,是一个迭代器
- 生成器对象,是延迟计算,惰性求值
- 举例:
>>> def inc():
for i in range(5):
yield i
>>> print(type(inc))
<class 'function'>
>>> print(type(inc()))
<class 'generator'>
>>> x = inc()
>>> print(type(x))
<class 'generator'>
>>> print(next(x))
0
>>> print(next(x))
1
2、生成器函数的调用
- 普通的函数调用fn(),函数会立即执行完毕,但是生成器函数可以使用next函数多次执行
- 生成器函数等价于生成器表达式,只不过生成器函数可以更加的复杂
- 举例
>>> def gen():
print('line 1')
yield 1
print('line 2')
yield 2
print('line 3')
return 3
•>>> next(gen())
line 1
1
>>> next(gen()) # 函数被重新调用,所以每次执行next返回值一样
line 1
1
>>> g = gen() # 同一个函数
>>> print(next(g))
line 1
1
>>> print(next(g))
line 2
2
>>> print(next(g))
line 3
Traceback (most recent call last):
File "<pyshell#33>", line 1, in <module>
print(next(g))
StopIteration: 3
备注:在生成器函数中,使用多个yield语句,执行一次后会暂停执行,把yield表达式的值返回;再次执行会执行到下一个yield语句,return语句依然可以终止函数运行,但函数返回值不能被获取到
3、yield from的使用
例如:
yield from的使用
def inc():
yield from range(10) #是一种语法糖
foo=int()
print(next(foo))
五、集合解析式
- 语法:{返回值 for i in 可迭代对象 if 条件}
- 列表解析式的中括号换成大括号就是集合解析式,返回是一个集合
- 如:{(x,x+1) for x in range(10)}
六、字典解析式
- 语法:{返回值 for i in 可迭代对象 if 条件}
- 列表解析式的中括号换成大括号就是集合解析式
- 使用key:value形式,返回一个字典
- 如:{x:(x,x+1) for x in range(10)
七、可迭代对象
- 能够通过迭代一次次返回不同的元素的对象,所谓相同不是指值是否相同,而是元素在容器中是否是同一个
- 可以迭代,但是未必有序,未必可索引
- 可迭代对象有:list,tupple,string,bytes,bytearray,range,set,dict,生成器等
- 可以使用成员操作符in, not in ,in本质上就是遍历对象
八、迭代器
- 特殊的对象,一定是可迭代对象,具备可迭代对象的特征
- 通过iter方法把一个可迭代对象封装成迭代器
- 通过next方法,迭代迭代器对象
- 生成器对象就是迭代器对象
for x in iter(range(10)):
print(x)
>>> g = ("{:0}".format(i) for i in range(1,11))
>>> type(g)
<class 'generator'>
>>> next(g)
'1'
>>> next(g)
'2'
>>>