import time
defgenrator_fun1():
a = 1
print('现在定义了a变量')
yield a
b = 2
print('现在又定义了b变量')
yield b
g1 = genrator_fun1()
print('g1 : ',g1) #打印g1可以发现g1就是一个生成器
print('-'*20) #我是华丽的分割线
print(next(g1))
time.sleep(1) #sleep一秒看清执行过程
print(next(g1))
2) 生成器函数的好处:可以避免一次性读取数据到内存中导致内存溢出
# 例子01:defproduce():"""生产衣服"""for i in range(2000000):
yield"生产了第%s件衣服"%i
product_g = produce()
print(product_g.__next__()) #要一件衣服
print(product_g.__next__()) #再要一件衣服
print(product_g.__next__()) #再要一件衣服
num = 0for i in product_g: #要一批衣服,比如5件
print(i)
num +=1if num == 5:
break#到这里我们找工厂拿了8件衣服,我一共让我的生产函数(也就是produce生成器函数)生产2000000件衣服。#剩下的还有很多衣服,我们可以一直拿,也可以放着等想拿的时候再拿# 例子02:import time
deftail(filename):
f = open(filename)
f.seek(0, 2) #从文件末尾算起whileTrue:
line = f.readline() # 读取文件中新的文本行ifnot line:
time.sleep(0.1)
continueyield line
tail_g = tail('tmp')
for line in tail_g:
print(line)
# 例子03:defaverager():
total = 0.0
count = 0
average = NonewhileTrue:
term = yield average
total += term
count += 1
average = total/count
g_avg = averager()
next(g_avg)
print(g_avg.send(10))
print(g_avg.send(30))
print(g_avg.send(5))
# 例子04:definit(func):#在调用被装饰生成器函数的时候首先用next激活生成器definner(*args,**kwargs):
g = func(*args,**kwargs)
next(g)
return g
return inner
@initdefaverager():
total = 0.0
count = 0
average = NonewhileTrue:
term = yield average
total += term
count += 1
average = total/count
g_avg = averager()
# next(g_avg) 在装饰器中执行了next方法
print(g_avg.send(10))
print(g_avg.send(30))
print(g_avg.send(5))
3) yield from
defgen1():for c in'AB':
yield c
for i in range(3):
yield i
print(list(gen1()))
以上是将生成器中的数据以列表的方式打印
以下的执行效果与上面相同,运用了yieldfrom 语法
defgen2():yieldfrom'AB'yieldfrom range(3)
print(list(gen2()))
⑤生成器函数进阶
send():
send和next的作用相同
第一次不能用send
函数中的最后一个yield不能接受新的值
# 计算移动平均值的例子defaverage():
sum = 0
count = 0
avg = 0whileTrue:
num = yield avg
sum += num
count += 1
avg = sum / count
avg_g = average()
avg_g.__next__()
print(avg_g.send(20))
print(avg_g.send(40))
print(avg_g.send(60))
# 预激生成器的装饰器——在装饰器中首先调用了__next__方法,方便用户直接进行调用definit(func):defwrapper(*args,**kwargs):
g = func(*args,**kwargs)
g.__next__()
return g
return wrapper
@initdefaverage():
sum,avg,count = 0,0,0whileTrue:
num = yield avg
sum += num
count += 1
avg = sum/count
avg_g = average()
print(avg_g.send(10))
print(avg_g.send(20))
print(avg_g.send(30))
⑥生成器表达式
'''
列表推导(列表生成式)
'''# 简单的列表推导
l = [i ** 2for i in range(10)]
print(l)
'''
生成器表达式
与列表推导相似,返回生成器对象
'''
g = (i ** 2for i in range(10))
# 生成器的第一种调用方式:__next__
print(g.__next__())
# 生成器的第二种调用方式:for循环for i in g:
print(i)
# 生成器的第三种调用方式:类型强转
print(list(g))
⑦各种推导式
'''
列表推导
[每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型] #遍历之后挨个处理
[满足条件的元素相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件] #筛选功能
'''# 简单的列表推导
l = [i ** 3for i in range(10)]
print(l)
>>> [0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
# 带筛选的列表推导
l = [i ** 3for i in range(10) if i % 3 == 0]
print(l)
>>> [0, 27, 216, 729]
# 多层列表推导
double_l = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
l = [name for lst in double_l for name in lst if name.count('e') >= 2]
print(l)
>>> ['Jefferson', 'Wesley', 'Steven', 'Jennifer']
'''
字典推导
'''# 例一:将一个字典的key和value对调
mcase = {'a': 10, 'b': 34}
mcase_frequency = {mcase[k]: k for k in mcase}
print(mcase_frequency)
>>> {34: 'b', 10: 'a'}
# 例二:合并大小写对应的value值,将k统一成小写
mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
mcase_frequency = {k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase.keys()}
print(mcase_frequency)
>>> {'b': 34, 'a': 17, 'z': 3}
'''
集合推导
'''# 计算列表中每个值的平方,自带去重功能
squared = {x ** 2for x in [1, -1, 2]}
print(squared)
>>> {1, 4}
'''
练习题
'''# 过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
lst = ['123', 'ab', 'y', 'abcabc', 'okiuj']
l = [i.upper() for i in lst if len(i) > 3]
print(l)
>>> ['ABCABC', 'OKIUJ']
# 答案# [name.upper() for name in names if len(name)>3]# 求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数组成的元组列表
lst = [(4, 3), (3, 2), (8, 1), (8, 6)]
t = [i for i in lst if ((i[0] % 2 == 0) and (i[1] % 2 != 0))]
print(t)
>>> [(4, 3), (8, 1)]
# 答案# [(x,y) for x in range(5) if x%2==0 for y in range(5) if y %2==1]# 求M中3,6,9组成的列表M = [[1,2,3],[4,5,6],[7,8,9]]
M = [[1,2,3],[4,5,6],[7,8,9]]
l = [i[2] for i in M]
print(l)
>>> [3, 6, 9]
# 答案# [row[2] for row in M]