在Python中哪里使用yield最好?

2024-05-17 16:26:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道yield是如何工作的。我知道排列,认为它只是一个数学简单。

但是yield的真正力量是什么?我应该什么时候用?一个简单而好的例子更好。


Tags: 数学例子yield力量
3条回答

另一个用途是在网络客户机中。在生成器函数中使用'yield'循环遍历多个套接字,而不需要复杂的线程。

例如,我有一个硬件测试客户机,需要将映像的R、G、B平面发送到固件。需要同步发送的数据:红、绿、蓝、红、绿、蓝。我没有生成三个线程,而是有一个从文件读取的生成器,对缓冲区进行编码。每个缓冲区都是“屈服缓冲区”。文件结束,函数返回,迭代结束。

我的客户机代码在三个生成器函数之间循环,在迭代结束之前获取缓冲区。

当您有一个返回序列的函数,并且您希望在该序列上迭代时,最好使用yield,但您不需要同时在内存中拥有每个值。

例如,我有一个python脚本,它解析一个CSV文件的大列表,我希望返回要在另一个函数中处理的每一行。我不想一次将兆字节的数据存储在内存中,所以我在python数据结构中的每一行yield。因此,从文件中获取行的函数可能类似于:

def get_lines(files):
    for f in files:
        for line in f:
            #preprocess line
            yield line

然后,我可以使用与with list相同的语法来访问此函数的输出:

for line in get_lines(files):
    #process line

但是我节省了很多内存。

简单地说,yield给你一个生成器。在通常在函数中使用return的地方使用它。作为一个真正做作的例子从一个提示剪贴。。。

>>> def get_odd_numbers(i):
...     return range(1, i, 2)
... 
>>> def yield_odd_numbers(i):
...     for x in range(1, i, 2):
...             yield x
... 
>>> foo = get_odd_numbers(10)
>>> bar = yield_odd_numbers(10)
>>> foo
[1, 3, 5, 7, 9]
>>> bar
<generator object yield_odd_numbers at 0x1029c6f50>
>>> bar.next()
1
>>> bar.next()
3
>>> bar.next()
5

如您所见,在第一种情况下,foo一次将整个列表保存在内存中。5个元素的列表没什么大不了的,但是如果你想要一个500万的列表呢?这不仅是一个巨大的内存消耗器,它也花费了大量的时间来构建时,该函数被调用。在第二种情况下,bar只是给你一个生成器。生成器是一个iterable——这意味着您可以在for循环等中使用它,但每个值只能访问一次。所有的值也不会同时存储在内存中;生成器对象“记住”上次调用它时它在循环中的位置--这样,如果使用iterable to(比方说)count to 500亿,就不必一次全部计数到500亿,并存储500亿个数以进行计数。再说一次,这是一个非常做作的例子,如果你真的想数到500亿,你可能会使用itertools。:)

这是生成器最简单的用例。正如您所说的,它可以用来编写有效的置换,使用yield通过调用堆栈向上推,而不是使用某种堆栈变量。生成器还可以用于专门的树遍历和所有其他事情。

进一步阅读:

相关问题 更多 >