更快的Python列表理解
我有一段代码在我的项目中运行了数千次:更快的Python列表理解,python,Python,我有一段代码在我的项目中运行了数千次: def resample(freq, data): output = [] for i, elem in enumerate(freq): for _ in range(elem): output.append(data[i]) return output 例如,重采样([1,2,3],'a','b','c'])=>['a','b','b','c','c'] 我想尽可能加快速度。似乎列表理解
def resample(freq, data):
output = []
for i, elem in enumerate(freq):
for _ in range(elem):
output.append(data[i])
return output
例如,重采样([1,2,3],'a','b','c'])
=>['a','b','b','c','c']
我想尽可能加快速度。似乎列表理解速度更快。我试过:
def resample(freq, data):
return [item for sublist in [[data[i]]*elem for i, elem in enumerate(frequencies)] for item in sublist]
这是可怕的,也是缓慢的,因为它建立了列表,然后将其展平。有没有一种方法可以快速理解一行列表?或者是跟numpy有关的
提前谢谢
编辑:答案不一定需要消除嵌套循环,最快的代码是最好的
import itertools
def resample(freq, data):
return itertools.chain.from_iterable([el]*n for el, n in zip(data, freq))
除了速度更快之外,它还具有惰性的优点,它返回一个生成器,元素一步一步地生成,根本不需要创建列表,只需使用嵌套循环:
[e for i, e in enumerate(data) for j in range(freq[i])]
# ['a', 'b', 'b', 'c', 'c', 'c']
您也可以通过删除括号轻松地将其设置为惰性:
(e for i, e in enumerate(data) for j in range(freq[i]))
我强烈建议使用如下发电机:
from itertools import repeat, chain
def resample(freq, data):
return chain.from_iterable(map(repeat, data, freq))
这可能是目前最快的方法-map()
、repeat()
和chain。from\u iterable()
都是用C实现的,所以从技术上讲,你不会有更好的方法
至于一个小小的解释:
repeat(i,n)
返回一个迭代器,该迭代器将一个项目重复i
,n次
map(repeat,data,freq)
返回迭代器,每次对data
元素和freq
元素调用repeat。基本上是一个返回repeat()
迭代器的迭代器
chain.from_iterable()
展平迭代器的迭代器以返回最终项
没有创建任何列表,因此没有开销,并且作为一个额外的好处,您可以使用任何类型的数据,而不仅仅是一个字符字符串
虽然我不建议这样做,但您可以将其转换为list()
,如下所示:
result = list(resample([1,2,3], ['a','b','c']))
列表理解并不比循环的等价运算快,因为它们执行完全相同的操作。只需使用[e表示i,e在枚举(y)表示j在范围(x[i])]内即可您所说的是什么类型的输入?如果freq
中的数字很大,那么在单个循环中使用extend
可能比append
更好。我不同意@jonrsharpe的结尾。这不是那个问题的重复。是的,我也不同意这个结论。一些快速测试似乎证实了这是迄今为止最快的答案。