【问题标题】:Pythonic pattern for building up parallel lists用于构建并行列表的 Pythonic 模式
【发布时间】:2016-12-13 18:17:47
【问题描述】:

我是 Python 新手,我发现我一遍又一遍地编写相同模式的代码:

def foo(list):
    results = []
    for n in list:
        #do some or a lot of processing on N and possibly other variables
        nprime = operation(n)
        results.append(nprime)
    return results

我正在特别考虑创建空列表,然后是 append 调用。有没有更 Pythonic 的方式来表达这种模式? append 可能没有最好的性能特征,但我不确定在 Python 中我还能如何处理它。

我经常确切地知道我的输出的长度,所以每次调用append 似乎可能会导致内存碎片或性能问题,但我也想知道这是否只是我以前的C 方式让我绊倒向上。我正在编写很多文本解析代码,这些代码对任何特定的循环或片段都不是超级性能敏感,因为所有性能实际上都包含在 gensimNLTK 代码中,并且比我更有能力。

是否有更好/更 Pythonic 的模式来执行这种类型的操作?

【问题讨论】:

  • 重复追加没问题。尝试预先分配您的列表,虽然可能,但不太可能提供实质性的性能改进,并且可能很容易减慢速度。
  • 你的意思是额外的处理排除了使用列表理解return [operation(n) for n in list]
  • 取决于some or a lot of processinglist comprehensions 或其近亲生成器表达式的数量,可以比简单的 for 循环提供速度或内存优势。但是,如果 some or a lot of processing 超过一两行代码,那么 for 循环肯定会在可读性和可维护性方面胜出。
  • 如果处理不像@chepner 建议的那样完全适合列表理解,那么您的 for 循环方法是下一个最佳选择。
  • 处理肯定不适合循环理解。

标签: python list python-3.x


【解决方案1】:

首先,您可能只需要一个列表理解(如果您的评论中提到的所有处理都发生在operation 中。

def foo(list):
    return [operation(n) for n in list]

如果列表推导在您的情况下不起作用,请考虑 foo 是否真的需要构建列表并且可以改为生成器。

def foo(list):
    for n in list:
        # Processing...
        yield operation(n)

这种情况下,可以对序列进行迭代,每个值都是按需计算的:

for x in foo(myList):
   ...

或者您可以让调用者决定是否需要完整列表:

results = list(foo())

如果以上都不合适,那么像现在这样在循环体中构建返回列表是完全合理的。

【讨论】:

  • 我认为我的代码中肯定有更多生成器的空间。可能有很多地方可以让我的代码读起来更好一些,并且编写得更好。谢谢! (我会看看还有什么,但我认为在适当的时候添加生成器是我正在寻找的答案并将其标记为这样)
【解决方案2】:

[..] 所以每次调用append 似乎都可能导致内存碎片或性能问题,但我也想知道这是否只是我的旧 C 方法让我绊倒。

如果您对此感到担心,请不要担心。当需要重新调整列表大小(列表根据其大小动态调整大小)以执行O(1) 追加时,Python 会过度分配。您可以手动调用list.append 或使用列表解析(内部 使用.append)构建它,内存方面的效果是相似的。

列表理解只是执行(速度方面)更好一点;它已针对使用专门的字节码指令创建列表进行了优化(LIST_APPEND 主要是直接 调用列表附加在C 中)。

当然,如果担心内存使用情况,您总是可以选择 chepners 回答中强调的生成器方法来懒惰地产生结果。


最后,for 循环仍然很棒。与理解和maps 相比,它们可能看起来很笨拙,但它们仍然提供了一种可识别且可读的方式来实现目标。 for 循环也值得我们喜爱。

【讨论】:

  • 更不用说列表理解需要使用for :)
猜你喜欢
  • 1970-01-01
  • 2010-10-29
  • 2012-12-24
  • 2020-12-10
  • 2021-12-05
  • 1970-01-01
  • 2019-03-14
  • 2017-04-17
相关资源
最近更新 更多