什么时候不是使用python生成器的好时机?

2024-04-24 09:26:53 发布

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

这与What can you use Python generator functions for?正好相反:python生成器、生成器表达式和itertools模块是我最近最喜欢的python特性。在设置操作链以对大量数据执行操作时,它们特别有用——我在处理DSV文件时经常使用它们。

那么,什么时候使用生成器、生成器表达式或itertools函数不是好时机呢?

  • 我什么时候应该选择zip()而不是itertools.izip(),或者
  • range()超过xrange(),或
  • [x for x in foo]超过(x for x in foo)

显然,我们最终需要将生成器“解析”为实际数据,通常是通过创建列表或使用非生成器循环对其进行迭代。有时我们只需要知道长度。这不是我要问的。

我们使用生成器,这样就不会为临时数据将新列表分配到内存中。这对于大型数据集尤其有意义。对小数据集也有意义吗?是否存在明显的内存/cpu权衡?

我特别感兴趣的是,如果有人在这方面做了一些分析,鉴于list comprehension performance vs. map() and filter()的令人大开眼界的讨论。(alt link


Tags: 数据内存inyou列表forfoo表达式
3条回答

轮廓,轮廓,轮廓。

分析您的代码是了解您正在做的事情是否有任何效果的唯一方法。

xrange、生成器等的大多数用途都是超静态大小、小数据集。只有当你接触到大数据集时,它才真正起作用。range()与xrange()的区别主要在于让代码看起来更难看一点,而且不会丢失任何东西,可能还会获得一些东西。

轮廓,轮廓,轮廓。

在以下情况下使用列表而不是生成器:

1)您需要多次访问数据(即缓存结果而不是重新计算结果):

for i in outer:           # used once, okay to be a generator or return a list
    for j in inner:       # used multiple times, reusing a list is better
         ...

2)您需要随机访问(或除正向顺序之外的任何访问):

for i in reversed(data): ...     # generators aren't reversible

s[i], s[j] = s[j], s[i]          # generators aren't indexable

3)需要连接字符串(需要两次传递数据):

s = ''.join(data)                # lists are faster than generators in this use case

4)您使用的是PyPy它有时无法通过正常的函数调用和列表操作尽可能优化生成器代码。

一般来说,当需要列表操作时,不要使用生成器,如len()、reversed()等。

有时,您可能不希望延迟计算(例如,提前完成所有计算,以便释放资源)。在这种情况下,列表表达式可能更好。

相关问题 更多 >