生成器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包行100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,到后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节约大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器: generator。
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator;
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
s = (x * 2 for x in range(10))
print(s)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object <genexpr> at 0x7fc84ad9c970> #生成器对象,不占用内存
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
s = [x * 2 for x in range(1000000000000)] #生成器,占用内存空间
print(s)
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
s = (x * 2 for x in range(1000000000000))
print(s)
print(s.__next__()) #调用生成器对象,特殊内部方法不建议使用
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object <genexpr> at 0x7f86e72c0970>
0
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
s = (x * 2 for x in range(1000000000000))
print(s)
print(next(s)) #建议使用这种方法,等价于s.__next__() in Py2:s.next()
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object <genexpr> at 0x7fe3f3340970>
0
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
s = (x * 2 for x in range(1000000000000))
print(s)
print(next(s))
print(next(s)) #只能按顺序
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object <genexpr> at 0x7fd034856970>
0
2
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
s = (x * 2 for x in range(5))
print(s)
print(next(s))
print(next(s))
print(next(s))
print(next(s))
print(next(s))
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object <genexpr> at 0x7f5978e08970>
0
2
4
6
8
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
s = (x * 2 for x in range(5))
print(s)
print(next(s))
print(next(s))
print(next(s))
print(next(s))
print(next(s))
print(next(s))
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object <genexpr> at 0x7fcc39039970>
0
2
4
6
8
Traceback (most recent call last):
File "/home/smoke/PycharmProjects/pythonProject/lean_python/generator.py", line 13, in <module>
print(next(s))
StopIteration
Process finished with exit code 1
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
s = (x * 2 for x in range(10))
print(s)
for i in s: #生成器就是一个可迭代对象(Iterable)
print(i)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object <genexpr> at 0x7f83455e2970>
0
2
4
6
8
10
12
14
16
18
Process finished with exit code 0
生成器一共两种创建方式:
1. (x*2 for x in range(5))
2. yield
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
def foo():
return 1
foo()
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
def foo():
yield 1 #生成器
print(foo)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<function foo at 0x7f8258ade280>
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
def foo():
print('ok')
yield 1
foo()
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
def foo():
print('ok')
yield 1
g = foo()
print(g)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object foo at 0x7f81759c9970>
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
def foo():
print('ok')
yield 1
g = foo()
print(g)
next(g)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object foo at 0x7fb2d513d970>
ok
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
def foo():
print('ok')
yield 1
print('ok2')
yield 2
g = foo()
print(g)
next(g)
next(g)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object foo at 0x7f737bfe2970>
ok
ok2
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
def foo():
print('ok')
yield 1
print('ok2')
yield 2
g = foo()
print(g)
next(g)
next(g)
next(g)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
Traceback (most recent call last):
File "/home/smoke/PycharmProjects/pythonProject/lean_python/generator.py", line 16, in <module>
next(g)
StopIteration
<generator object foo at 0x7fba927f7970>
ok
ok2
Process finished with exit code 1
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
def foo():
print('ok')
yield 1
print('ok2')
yield 2
g = foo()
print(g)
for i in foo():
print(i)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object foo at 0x7f35c01d5970>
ok
1
ok2
2
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
def foo():
print('ok')
yield 1 #返回值,类似return 1
print('ok2')
yield 2
g = foo()
print(g)
print(next(g))
print(next(g))
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object foo at 0x7ff2a4e91970>
ok
1
ok2
2
Process finished with exit code 0
什么是可迭代对象,有__iter__()方法
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
#什么是可迭代对象,有__iter__()方法
l = [1,2,3]
l.__iter__()
t = (1,2,3)
t.__iter__()
d = {'name':'123'}
d.__iter__()
斐波拉契数列
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
# 0 1 1 2 3 5 8 13 21
def fib(max):
n, before, after = 0, 0, 1
while n < max:
print(after)
before, after = after, before + after
n = n + 1
fib(10)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
1
1
2
3
5
8
13
21
34
55
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
# 0 1 1 2 3 5 8 13 21
def fib(max):
n, before, after = 0, 0, 1
while n < max:
print(after)
# before, after = after, before + after
old_before = before
before = after
after = old_before + after
n = n + 1
fib(10)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
1
1
2
3
5
8
13
21
34
55
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
# 0 1 1 2 3 5 8 13 21
def fib(max):
n, before, after = 0, 0, 1
while n < max:
print(before)
# before, after = after, before + after
old_before = before
before = after
after = old_before + after
n = n + 1
fib(8)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
0
1
1
2
3
5
8
13
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
# 0 1 1 2 3 5 8 13 21
def fib(max):
n, before, after = 0, 0, 1
while n < max:
# print(before)
yield before
# before, after = after, before + after
old_before = before
before = after
after = old_before + after
n = n + 1
print(fib(8))
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object fib at 0x7f0d1a8a0970>
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
# 0 1 1 2 3 5 8 13 21
def fib(max):
n, before, after = 0, 0, 1
while n < max:
# print(before)
yield before
# before, after = after, before + after
old_before = before
before = after
after = old_before + after
n = n + 1
g = fib(8)
print(g)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object fib at 0x7f44890ef970>
0
1
1
2
3
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
# 0 1 1 2 3 5 8 13 21
def fib(max):
n, before, after = 0, 0, 1
while n < max:
# print(before)
yield before
# before, after = after, before + after
old_before = before
before = after
after = old_before + after
n = n + 1
g = fib(8)
print(g)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
<generator object fib at 0x7f2436b5a970>
0
1
1
2
3
5
8
13
Traceback (most recent call last):
File "/home/smoke/PycharmProjects/pythonProject/lean_python/generator.py", line 29, in <module>
print(next(g))
StopIteration
Process finished with exit code 1
send()
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
def bar():
print('ok1')
yield 1
print('ok2')
yield 2
b = bar()
next(b)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
ok1
ok2
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
def bar():
print('ok1')
count = yield 1
print(count)
print('ok2')
yield 2
b = bar()
b.send(None) #next(b)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
ok1
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
def bar():
print('ok1')
count = yield 1
print(count)
print('ok2')
yield 2
b = bar()
s = b.send(None) #next(b),第一次send前没有next()只能传一个send(None)
print(s)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
ok1
1
Process finished with exit code 0
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
def bar():
print('ok1')
count = yield 1
print(count)
yield 2
b = bar()
b.send(None) #next(b)
b.send('eeee')
#!/usr/bin/env python3.8
# __author: "smoke"
# date: 2021/1/15 下午9:59
def bar():
print('ok1')
count = yield 1
print(count)
yield 2
b = bar()
next(b)
ret = b.send('eeee')
print(ret)
/home/smoke/PycharmProjects/pythonProject/venv/bin/python /opt/pycharm/pycharm-2020.2.3/plugins/python/helpers/pydev/pydevd.py --multiproc --qt-support=auto --client 127.0.0.1 --port 39905 --file /home/smoke/PycharmProjects/pythonProject/lean_python/generator.py
Connected to pydev debugger (build 203.6682.179)
ok1
eeee
2
Process finished with exit code 0
浙公网安备 33010602011771号