生成器:就是自己用python代码写的迭代器,生成器的本质就是迭代器。
# 函数 def func1(x): x += 1 return x func1(5) #函数的执行命令,并且接受函数的返回值。 print(func1(5)) # 生成器函数 def func1(x): x += 1 print(1111) print(1111) print(1111) print(1111) print(1111) print(1111) yield x x +=2 print(2222) yield 'alex' a = func1(1) print(a.__next__()) print(a.__next__())
一个next 对应一个yield yield将返回值给生成器对象 .__next__()
yield 和 return 比较
return 结束函数,给函数执行者返回值
yield 不会结束函数,一个next 对应一个yield 给生成器对象.__next__()返回值
生成器函数与迭代器区别。
1迭代器需要可迭代对象进行转换,可迭代对象非常占内存
2 生成器直接创建,不需要转换,从本质就节约内存
def func1(): for i in range(1000000): yield i g1 = func1() for i in range(50): print(g1.__next__()) #打印了0到49的数字
send 与 next
send 与next一样,也是对生成器取值(执行一个yield)的方法。
send 可以给上一个yield 传值。
第一次取值永远都是next。
最后一个yield 永远也得不到send传的值。 不然就会报错
# def cloth1(n): # for i in range(n+1): # print('衣服%s号' % i) # cloth1(100000) # def cloth2(n): # for i in range(1,n+1): # yield '衣服%s号' % i # g = cloth2(10000) # for i in range(50): # print(g.__next__()) # for i in range(50): # print(g.__next__()) 后面取值会直接从50开始取
列表推导式: 一行代码几乎搞定你需要的任何列表
循环模式---------[变量(加工后的变量) for 变量 in iterable]
# l1 = [] # for num in range(1,101): # l1.append(num) 列表中有1到100的数 列表推导式# l = [i for i in range(1,101)] # l2 = ['python%s期' % i for i in range(1,16)] 格式化输入 %s 替代 # print([i*i for i in range(1,11)]) i 的平方
# 筛选模式 [变量(加工后的变量) for 变量 in iterable if 条件] # l3 = [i for i in range(1,31) if i % 2 == 0] # print(l3) # print([i for i in range(1,31) if i % 3 == 0]) # print([i**2 for i in range(1,31) if i % 3 == 0]) names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] print([j for i in names for j in i if j.count('e') == 2])
列表推导式
优点:一行解决
缺点:容易着迷,不易排错,不能超过三次循环,太大的数据就不要用了
列表推导式不能解决所有列表的问题,所有不要太刻意用
生成器表达式,把 [ ] 换成 () 即可