更快的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的结尾。这不是那个问题的重复。是的,我也不同意这个结论。一些快速测试似乎证实了这是迄今为止最快的答案。