迭代器、生成器
生成器:就是自己python用代码写的迭代器,生成器的本质就是迭代器。
12l1 = [1,2,3]
iter1 = iter(l1)
用以下两种方式构建一个生成器
- 通过生成器函数。
- 生成器表达式。
函数:
12345def func1(x): x += 1 return x func1(5) #函数的执行命令,并且接受函数的返回值。 print(func1(5))
生成器函数:
12345678910def func1(x): x += 1 print(1) yield x g_obj = func1(5)#生成器函数对象 print(g_obj) #<generator object func1 at 0x000001AD4C6DC0F8> print(g_obj.__next__()) print(g_obj.__next__()) #一个next 对应一个 yield #yield 将值返回给 生成器对象.__next__()
yield ,return
return 结束函数,给函数的执行者返回值
yield 不会结束函数,一个next对应一个yield,给 生成器对象.__ next__()返回值。
生成器函数 vs 迭代器
1.自定制的区别
1234567891011def func1(x): x += 1 yield x x += 3 yield x x += 5 yield x g1 = func1(5) print(g1.__next__()) print(g1.__next__()) print(g1.__next__())
区别:内存级别的区别。
迭代器是需要可迭代对象进行转化,可迭代对象非常占内存。
生成器直接创建,不需要转化,从本质就节省内存。
123456def func1(x): for i in renge(100000): yield i gl = func1() for i in range(50) print(g1.__next__())
send 与 next
123456789101112def func1(): print(1) count = yield 6 print(count) print(2) yield 7 print(3) yield 8 g = func1(): print(next(g)) print(g.send('alex')) print(next(g))
- send 与next一样,也是对生成器取值(执行一个yield)的方法。
- send 可以给上一个yield传值。
- 第一次取值永远都是next,最后一个yield 永远也得不到send传的值。
123456789101112#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__())
列表推导式
一行代码几乎搞定你需要的任何的列表。
- 循环模式 变量(加工后的变量) for 变量 in iterable]
print([i for i in range(1,101)])
- 筛选模式
print([i for i in range(1,31)if i % 3 == 0])
优点:一行解决,方便。
缺点:容易着迷,不易排错,不能超过三次循环。
列表推导式不能解决所有列表的问题,所以不要太刻意用。
生成器表达式
将列表推导式的[]换成()即可。
g = (i for i in range(10000)) print(g.__next__())
生成器Generator:
本质:迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现)
特点:惰性运算,开发者自定义