生成器/内置函数
生成器
本质就是迭代器,手动写的迭代器
生成器函数
def func():
print (123)
yield '生成器'
func() ## 执行结果 :没有结果
'''******'''
ret = func() ## 这个过程相当于 实例化对象
'''******'''
print(ret) #<generator object func at 0x000002A9298C3F48>生成器对象
# 想执行这个 要用next() 和迭代器一样 或者遍历它
next(ret) ## 123
print(next(ret)) ## 111 2 # 如果生成器中没有yield了,再调用next会报错
生成器函数的坑(1)
## for循环中的生成器
def add(n, i):
return n+i
def test():
for i in range(4):
yield i
g = test()
for n in [1, 10, 5]:
g = (add(n, i) for i in g)
print(list(g)) # 结果是 [15, 16, 17, 18]
## 关键点在于生成器相当于函数,不调用就不执行,只有最后list(g)了,才一层一层的解开
# for循环3次 相当于
n = 1
g = ((n+i) for i in test())
n = 10
g = ((n+i) for i in g(此时的g是((n+i) for i in test()) ))
n = 5
g = ((n+i) for i in g(此时的g是 ((n+i) for i in ((n+i) for i in test()) )))
list(g) 的时候才 开始执行这个表达式 此时n已经是 5 了
## 最后的结果也就是循环几层,取几次5,再与g的各项相加取值
5*3+0,5*3+1,5*3+2,5*3+3
生成器的坑(2)
def demo():
for i in range(4):
yield i
g=demo()
g1=(i for i in g)
g2=(i for i in g1)
print(list(g1))## list(g1)相当于在底层for循环,也就是next(g1),到最后一层
print(list(g2)) ## 所以当list(g2)时,for遍历g1,next(g1)指不到东西
生成器的坑(3)
v = (lambda :x for x in range(10))
print(v)
print(next(v))
print(next(v)())
## 生成器地址
## 匿名函数地址
## 1 因为 生成器是next() 一次执行一次, 上一次next执行到 x = 1 所以这次执行匿名函数返回1(生成器表达式,next一次可以理解为里面的代码走一圈)
## 生成器 next执行一次 for 循环 执行到底 list() 执行到底
yield
阻塞
return 和 yield
## return 结束函数,给函数的执行者返回值
## yield 不结束函数,给next(func()) 返回值
yield from
def func():
l = [1,2,3]
yield from l
fun = func()
print (next(fun)) # 1
print (next(fun))# 2
print (next(fun))# 3,
## 取代了for循环,将可迭代对象中的每一项元素依次取出来
匿名函数
lambda x,y:x+y
不调用,不执行,不调用,不执行
列表推导式 生成器表达式
## 列表推导式
l = [i for i in iterable if i...]
## 一行代码实现九九乘法表
'\n'.join([' '.join([f'{j}*{i}={j*i}'for j in range(1,i+1)]) for i in range(1,10)])
# 生成器表达式
obj = (i for i in iterable if i...)
## 取值方式
# 第一种
print(next(obj))
# 第二种
for i in obj:
print(i)
# 第三种
print (list(obj))
内置函数
min
# 参数列表可以放key的
min()
max()
sorted()
# 例如 min()
dic = {'a':1,'b':2,'c':3,'d':0}
print(min(dic)) # 此时返回的结果为 a
print (min(dic,key=lambda x:x)) ## 相当于将dic遍历传入 lambda表达式(函数)中,return 的是什么就按照什么比较,这个x是dic的key,所以返回的也是字典的key
zip
## zip ## 将传入的可迭代对象,按相同索引组合成一个元组,直到其中一项到索引最后一项
def zipp(*iterable):
obj = object()
iterators = [iter(it) for it in iterable]
while iterators:
result = []
for it in iterators:
em = next(it,obj)
if em is obj:
return
result.append(em)
yield tuple(result)
a = zipp('asd','zxc','qwe')
while 1:
try:
print(next(a))
except:
break
print(list(a)) # [('a', 'z', 'q'), ('s', 'x', 'w'), ('d', 'c', 'e')]
## 返回的是迭代器对象
filter
## 过滤
filter(func,lst)
lst = [{'id':1,'name':'alex','age':18},
{'id':1,'name':'wusir','age':17},
{'id':1,'name':'taibai','age':16},]
ls = filter(lambda e:e['age'] > 16,lst)
print(list(ls))
结果:
[{'id': 1, 'name': 'alex', 'age': 18},
{'id': 1, 'name': 'wusir', 'age': 17}]
## 返回的是迭代器对象
map
# map 映射函数
lis = [1,2,3,4,5]
for i in map(lambda x:x**2,lis):
print(i)
# 1,4,9,16,25
lis1 = [1,2,3,4,5]
m1 = map(lambda x,y:x+y,lis,lis2)
for i in m1:
print(i) # 2,
4,6,8,10
## 返回的是迭代器对象
reduce
## 归并函数
from functools import reduce
l = [1,2,3,4]
ret = reduce(lambda x,y:x*y,l)
print(ret)
## 解决阶乘
# 返回的是值