关于python:unspool频率表(按列表理解)

Unspool frequency table by list comprehension

这里有一个频率表作为列表实现。

1
table = [1,3,2]

所需的输出是单个值的列表。

1
unspooled =  [0, 1, 1, 1, 2, 2]

以下语法将完成该作业。

1
sum((freq*[score] for score, freq in enumerate(table)), [])

不过,作为一个测试我理解力的练习,我想知道是否有一种方法可以通过纯粹的列表理解来实现这一点。谢谢您。

(或者第二,如果有一种方法比我所拥有的那些不纯粹的列表理解更具表现力,那么我也愿意这样做。)

显然,我的语法产生了糟糕的性能。

更新。所有建议解决方案的时间安排。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
In [9]: table
Out[9]: range(0, 1000)

In [10]: %timeit [i for i, x in enumerate(table) for _ in range(x)]
10 loops, best of 3: 27.1 ms per loop

In [11]: %timeit [ind for ind in range(len(table)) for val in range(table[ind])]
10 loops, best of 3: 27 ms per loop

In [12]: %timeit reduce( lambda x,y:x+y, [ [i]*frq for i,frq in enumerate(table)] )
1 loop, best of 3: 1.11 s per loop

In [13]: %timeit list(itertools.chain(freq*[score] for score, freq in enumerate(table))
100 loops, best of 3: 3.84 ms per loop

您可以使用enumerate返回table中的索引和项目:

1
2
3
>>> table = [1,3,2]
>>> [i for i, x in enumerate(table) for _ in range(x)]
[0, 1, 1, 1, 2, 2]

我相信这是可行的:

1
unspooled = [ind for ind in range(len(table)) for val in range(table[ind])]


1
2
3
4
5
table = [1,3,2]
res = reduce( lambda x,y:x+y, [ [i]*frq for i,frq in enumerate(table)] )

output:
[0, 1, 1, 1, 2, 2]