Python生成器是返回遍历对象并用于创建迭代器的函数,它一次遍历整个项目。生成器也可以是一个表达式。
在Python中创建迭代有很多复杂性。无涯教程需要实现 __ iter __()和 __ next __()方法来跟踪内部状态。
创建迭代器是一个漫长的过程。因此,生成器在简化此过程中起着至关重要的作用。如果在迭代中找不到任何值,则会引发 StopIteration 异常。
在Python中创建生成器非常简单。它与 def 关键字定义的常规函数相似,并使用 yield 关键字而不是return。或者可以说,如果任何函数的主体包含 yield 语句,它将自动成为生成器函数。考虑以下示例:
def simple(): for i in range(10): if(i%2==0): yield i #使用 for 循环的连续函数调用 for i in simple(): print(i)
输出:
0 2 4 6 8
yield 语句负责控制生成器函数的流程。它通过保存所有状态并让出给调用者来暂停函数执行。稍后,当调用后续函数时,它将恢复执行。可以在生成器函数中使用多产量声明。
return语句返回,并终止整个函数,并且该函数中只能使用一个return语句。可以在生成器函数中使用多个yield声明。
def multiple_yield(): str1 = "First String" yield str1 str2 = "Second string" yield str2 str3 = "Third String" yield str3 obj = multiple_yield() print(next(obj)) print(next(obj)) print(next(obj))
输出:
First String Second string Third String
可以轻松创建生成器表达式,而无需使用用户定义的函数。它与创建匿名函数的lambda函数相同;生成器的表达式创建一个匿名生成器函数。
唯一的区别是方括号被圆括号替换。列表推导计算整个列表,而生成器表达式一次计算一次。
考虑以下示例:
list = [1,2,3,4,5,6,7] # List Comprehension z = [x**3 for x in list] # Generator expression a = (x**3 for x in list) print(a) print(z)
输出:
<generator object <genexpr> at 0x01BA3CD8> [1, 8, 27, 64, 125, 216, 343]
在上面的程序中,列表理解返回了元素立方体的列表,而生成器表达式返回了计算值的引用。除了应用 for循环,还可以在生成器对象上调用 next()。
list = [1,2,3,4,5,6] z = (x**3 for x in list) print(next(z)) print(next(z)) print(next(z)) print(next(z))
输出:
1 8 27 64
在上面的程序中,使用了 next()函数,该函数返回了列表的下一项。
示例:编写一个程序,使用生成器打印给定编号的表格。
输出:
15 30 45 60 75 90 105 120 135 150
在上面的示例中,生成器函数使用for循环进行迭代。
生成器具有各种优点。其中很少给出如下:
1.易于实施 - 与迭代器相比,生成器易于实现。在迭代器中,必须实现 __ iter __()和 __ next __()函数。
2.高效存储 - 生成器对于大量序列具有存储效率。普通函数返回列表的序列,该列表在返回结果之前在内存中创建整个序列,但是生成器函数计算该值并暂停其执行。继续进行后续呼叫。在下面的示例中,使用 sys.getsizeof()函数对其进行讨论。
import sys # List comprehension nums_squared_list = [i * 2 for i in range(1000)] print(sys.getsizeof("Memory in Bytes:"nums_squared_list)) # 生成器表达式 nums_squared_gc = (i ** 2 for i in range(1000)) print(sys.getsizeof("Memory in Bytes:", nums_squared_gc))
输出:
Memory in Bytes: 4508 Memory in Bytes: 56
从上面输出中可以看到,列表推导正在使用4508字节的内存,而生成器表达式正在使用56字节的内存。这意味着生成器对象比列表压缩有效得多。
3.用生成器流水线 - 数据管道提供了无需使用额外的计算机内存即可处理大型数据集或数据流的函数。
假设有一家著名餐厅的日志文件。日志文件中有一列(第4 列 )用于跟踪每小时售出的汉堡数量,希望对其进行汇总以得出4年内售出的汉堡总数。在这种情况下,生成器可以生成具有一系列操作的管道。下面是它的代码:
with open('sells.log') as file: burger_col = (line[3] for line in file) per_hour = (int(x) for x in burger_col if x != 'N/A') print("Total burgers sold = ",sum(per_hour))
4.产生无限序列 - 生成器可以产生无限的物品。无限序列不能包含在内存中,并且由于生成器一次只生成一项,请考虑以下示例:
def infinite_sequence(): num = 0 while True: yield num num += 1 for i in infinite_sequence(): print(i)
输出:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ......... .......... 315 316 317 Traceback (most recent call last): File "C:\Users\DEVANSH SHARMA\Desktop\generator.py", line 33, in <module> print(i) KeyboardInterrupt
祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)