用于建立并行列表的Pythonic模式
我是Python新手,我发现我正在一次又一次地编写相同的代码模式:用于建立并行列表的Pythonic模式,python,list,python-3.x,Python,List,Python 3.x,我是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 我特别考虑创建空列表
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
调用。有没有一种更像蟒蛇的方式来表达这种模式append
可能没有最好的性能特性,但我不确定在Python中如何实现它
我通常知道输出的确切长度,因此每次调用append
似乎可能会导致内存碎片或性能问题,但我也想知道这是否只是我以前的C
方法让我感到困惑。我正在编写很多文本解析代码,这些代码对任何特定循环或片段的性能都不太敏感,因为所有性能实际上都包含在gensim
或NLTK
代码中,而且比我的能力更强
是否有更好/更具python风格的模式来执行这种类型的操作?首先,您可能只需要理解列表(如果您的注释中提到的所有处理都发生在
操作中)
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())
如果以上两种方法都不合适,那么在循环体中建立返回列表是完全合理的
[…]因此,每次调用append
似乎都可能导致内存碎片或性能问题,但我也在想,这是否只是我以前的C方式绊倒了我
如果您对此感到担忧,请不要担心。当需要重新调整列表的大小(列表根据其大小动态调整大小)以执行O(1)
appends时,Python会过度分配。您可以手动调用list.append
,也可以使用列表理解(内部也使用.append
)就记忆而言,效果是相似的
列表理解的性能(速度方面)稍微好一点;它被优化用于创建具有专门字节码指令的列表,这些指令有助于它(list\u APPEND
,主要是在C
中直接调用lists APPEND)
当然,如果内存使用是一个问题,您可以选择chepners答案中突出显示的生成器方法来懒散地生成结果
最后,for
循环仍然很好。与理解和map
s相比,它们可能看起来很笨拙,但它们仍然提供了一种可识别和可读的方式来实现目标。for
循环也值得我们的喜爱。重复追加是可以的。尝试预先分配列表,虽然可能,但不太可能证明ide极大地提高了性能,并且可能很容易减慢速度。您是说额外的处理会阻止使用列表理解return[操作(n)for n in list]
?根据部分或大量处理的数量,或者它们的近亲生成器表达式可以比简单for循环提供速度或内存优势。如果部分或大量处理
超过一两行代码,则for循环肯定会在可读性和可维护性方面胜出。如果ing不能像@chepner所建议的那样完全融入列表理解,for-loop方法是下一个最好的选择。处理过程肯定不适合循环理解。我认为我的代码中肯定有空间容纳更多生成器。可能有很多地方可以让我的代码读起来更好,组成起来更好。谢谢!(我会看看还有什么,但我认为在适当的时候添加生成器是我要寻找的答案,并将其标记为这样)更不用说列表理解需要使用for
:)