- 一、列表解析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' >>>