一、生成器
1.1 生成器:就是(python)自己用代码写的迭代器,生成器的本质就是迭代器。
1.2 生成器函数
def func1(x): x +=1 print(111) yield x print(222) yield 'alex' g_obj = func1(5) # 生成器函数对象 print(g_obj) # <generator object func1 at 0x000002760D700BA0> print(g_obj.__next__()) print(g_obj.__next__())
注意:
(1)一个next对应一个yield
(2)yield 降值返回给 生成器对象.__next__()返回值。
1.2.1 yield 与 return 的区别
(1)return 结束函数,给函数的执行者返回值
(2)yield 不会结束函数,一个next对应一个yield,给生成器对象.__next__()
1.3 迭代器VS生成器
区别1:自定制的区别
迭代器
l1= [1,2,3,4] l1.__iter__()
生成器
def func1(x): x += 1 yield x x += 3 yield x x += 5 yield x g1 = func1(5) for i in range(3): print(g1.__next__())
区别2:内存级别的区别
(1)迭代器是需要可迭代对象进行转化。可迭代对象非常占内存。
(2)生成器直接创建,不需要转化,从本质就节省内存。
def func1(): for i in range(1,100): yield i g1 = func1() for i in range(50): print(g1.__next__())
1.4 send 与 next的区别
(1)send 与 next 一样,也是对生成器取值(执行一个yield)的方法。
(2)send 可以给上一个yield传值。
(3)第一个取值永远都是next。
(4)最后一个yield永远也得不到send传的值。
def func1():
print(111)
count = yield 6 # 返回值用count去接受
print(count)
print(222)
yield 7
print(333)
yield 8
g = func1()
print(next(g))
print(g.send('alex'))
# print(next(g))
print(next(g))
结果为:
111
6
alex
222
7
333
8
1.5 生成器的应用
第一种: def cloth(n): for i in range(1,n+1): print('衣服%s'%i) cloth(10) 第二种: def cloth(n): for i in range(1,n+1): yield '衣服%s'%i g = cloth(10) for i in range(5): print(g.__next__()) for i in range(5): print(g.__next__())
二、列表的推导式
2.1 利用for循环写1-100的列表
l1 = [] for i in range(1,101): l1.append(i) print(l1)
2.2 利用列表推导式:一行列表搞定你需要的任何列表。
l1 = [i for i in range(1,100)] print(l1)
2.2.1 循环模式 [变量(加工后的变量) for 变量 in iterable(可迭代对象)]
l2 = ['python%s期' % i for i in range(1, 10)] print(l2)
l3 = [i**2 for i in range(1,10)] print(l3)
2.2.2 筛选模式:[变量(加工后的变量)for 变量 in iterable if 条件]
l4 = [i for i in range(1,10) if i % 2 == 0] print(l4)
# 加工后的变量 l5 = [i**2 for i in range(1,31) if i % 3 == 0] print(l5)
# 双层循环 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] l1 = [j for i in names for j in i if j.count('e') == 2] print(l1)
2.3 列表推导式的优缺点
(1)优点:一行解决,方便
(2)缺点:容易着迷,不易排错,不能超过三次循环。
(3)列表推导式不能解决所有列表的问题,所以不要太刻意用。
三、生成器表达式:将列表推导式的 [ ] 换成()即可
g = (i for i in range(100)) print(g) # 生成器函数对象 <generator object <genexpr> at 0x000001B44A1C0BA0> for i in range(10): print(g.__next__())
四、字典键值对互换
mcase = {'a':10,'b':34} mcase_frequency = {mcase[k]: k for k in mcase} print(mcase_frequency)
五、集合推导式
squared = {x**2 for x in [1,-1,2]} print(squared)