python简单进阶,Generator

Generator

看完了上一篇python简单进阶,Iteration,再看这一篇。

1、先看看一个比较精简的说明

the differences between Generator function and a Normal function:

1.Generator函数包含一个 yield语句
2.当调用这个函数的时候,并不立即执行,而是返回一个iterator
3. __iter__()__next__()等iterator必须包含的函数都是自动实现的
4. 一旦Generator函数执行,这个函数就会暂停在yield的位置,线程的执行权交给函数的调用者
5. 执行结束的时候,会自动raise StopIteration的异常

2、简单的实现一下

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

看了上面这个例子相信会有比较好的帮助

3、Generator有什么用?怎么使用?

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

Why generators are used in Python?

  1. Easy to Implement
  2. Memory Efficient(A normal function to return a sequence will create the entire sequence in memory before returning the result.This is an overkill, if the number of items in the sequence is very large.Generator implementation of such sequences is memory friendly and is preferred since it only produces one item at a time.)
  3. Represent Infinite Stream
  4. Pipelining Generators

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

猜你喜欢

转载自blog.csdn.net/qq_40666620/article/details/107897847