看完了上一篇python简单进阶,Iteration,再看这一篇。
the differences between Generator function and a Normal function:
1.Generator函数包含一个 yield语句
2.当调用这个函数的时候,并不立即执行,而是返回一个iterator
3. __iter__()
和__next__()
等iterator必须包含的函数都是自动实现的
4. 一旦Generator函数执行,这个函数就会暂停在yield的位置,线程的执行权交给函数的调用者
5. 执行结束的时候,会自动raise StopIteration的异常
def my_gen():
n = 1
print("this is the first print")
yield n
n += 1
print("this is the second print")
yield n
n += 1
print("this is the third print")
yield n
for item in my_gen():
print(item)
执行结果
this is the first print
1
this is the second print
2
this is the third print
3
或者这样写
def my_gen():
n = 1
print("this is the first print")
yield n
n += 1
print("this is the second print")
yield n
n += 1
print("this is the third print")
yield n
b = my_gen()
b.__next__()
b.__next__()
b.__next__()
执行结果
this is the first print
this is the second print
this is the third print
看了上面这个例子相信会有比较好的帮助
Normally, generator functions are implemented with a loop having a suitable terminating condition.
通常来说,generator 函数的实现会伴随着具有合适终止条件的循环。
def rev_ste(my_str):
length = len(my_str)
for i in range(length - 1, -1, -1):
yield my_str[i]
for char in rev_ste("hello"):
print(char, end=' ')
执行结果
o l l e h
Similar to the lambda functions which create anonymous functions,
generator expressions create anonymous generator functions.
The major difference between a list comprehension and a generator expression is that
a list comprehension produces the entire list while the generator expression produces one item at a time.
更少的内存使用,比等价的列表要好的多啊
They have lazy execution ( producing items only when asked for ).
For this reason, a generator expression is much more memory efficient than an equivalent list comprehension.
my_list = [1, 2, 3, 4]
list_ = [x ** 2 for x in my_list]
generator = (x ** 2 for x in my_list)
print(list_)
print(generator)
for x in generator:
print(x)
执行结果
[1, 4, 9, 16]
<generator object <genexpr> at 0x000001302A19A228>
1
4
9
16
Generator expressions can be used as function arguments.
When used in such a way, the round parentheses can be dropped.
my_list = [1, 2, 3, 4]
print(sum(x ** 2 for x in my_list))
print(max(x ** 2 for x in my_list))
执行结果
30
16
写一个2的幂次方
# 用generator生成一个可迭代的序列,每次yield返回执行结果
def my_test_method(max):
for i in range(0, max, 1):
yield 2 ** i
for item in my_test_method(10):
print(item)
执行结果
1
2
4
8
16
32
64
128
256
512
Pipelining Generators例子
#计算斐波那契的下一项
def fibonacci_numbers(nums):
x, y = 0, 1
for _ in range(nums):
x, y = y, x + y
yield x
# 根据fibonacci_numbers返回的下一个斐波那契数字,返回平方
def square(nums):
for num in nums:
yield num ** 2
# 计算和
print(type(fibonacci_numbers(10)))
print(type(square(fibonacci_numbers(10))))
print(sum(square(fibonacci_numbers(10))))
执行结果
<class 'generator'>
<class 'generator'>
4895