我有一个列表的Python列表:
l = [[1, 2, 3], [4], [5, 6], [7, 8, 9, 10]]
我想要的是根据列表的长度重复每个列表的第一个元素:
result = [1, 1, 1, 4, 5, 5, 7, 7, 7, 7]
我可以使用列表理解来实现这一点,但我的列表很长,所以方法很慢:
result = [[x[0]]*len(x) for x in l]
[[1, 1, 1], [4], [5, 5], [7, 7, 7, 7]]
虽然,这仍然会返回列表而不是平面列表。所以,我试图找出基于上述标准创建该平面列表的最快方法。
更新:由于列表很长,我想要性能最快的方法
答案 0 :(得分:2)
您可以使用itertools.chain来平展结果。
import itertools
l = [[1, 2, 3], [4], [5, 6], [7, 8, 9, 10]]
res = list(itertools.chain(*[[i[0]]*len(i) for i in l]))
print (res)
收率:
[1, 1, 1, 4, 5, 5, 7, 7, 7, 7]
根据 @PadraicCunningham 建议,可以在比较中使用比itertools.chain.from_iterable
更快的itertools.chain
。
import timeit
case1 = lambda: list(itertools.chain(*[[i[0]]*len(i) for i in l]))
case2 = lambda: list(itertools.chain.from_iterable([[i[0]]*len(i) for i in l]))
print ("time required by Case1 to execute :", timeit.timeit(case1))
print ("time required by Case1 to execute :", timeit.timeit(case2))
显示两种情况的时间报告:
time required by Case1 to execute : 4.83640388816
time required by Case1 to execute : 4.68654976762
答案 1 :(得分:1)
>>> [i[0] for i in l for _ in range(len(i))]
[1, 1, 1, 4, 5, 5, 7, 7, 7, 7]
答案 2 :(得分:1)
你可以这样做,
>>> l = [[1, 2, 3], [4], [5, 6], [7, 8, 9, 10]]
>>> [i for x in l for i in [x[0]]*len(x)]
[1, 1, 1, 4, 5, 5, 7, 7, 7, 7]
答案 3 :(得分:1)
>>> l = [[1, 2, 3], [4], [5, 6], [7, 8, 9, 10]]
>>> reduce(lambda x,y: x+y,map(lambda x:[x[0]]*len(x),l))
[1, 1, 1, 4, 5, 5, 7, 7, 7, 7]
1 这样你就可以学习新的python模块了。
答案 4 :(得分:1)
使用itertools.repeat
和chain
使用python 2是最有效的:
In [13]: l = [choice(l) for _ in xrange(1000000)]
In [14]: timeit list(itertools.chain(*[[i[0]]*len(i) for i in l]))
1 loops, best of 3: 416 ms per loop
In [15]: timeit [i[0] for i in l for _ in xrange(len(i))]
1 loops, best of 3: 245 ms per loop
In [16]: timeit list(itertools.chain.from_iterable(repeat(i[0],len(i)) for i in l))
1 loops, best of 3: 223 ms per loop
In [17]: timeit [i for x in l for i in [x[0]]*len(x)]
1 loops, best of 3: 332 ms per loop
有趣的是使用python3
,使用列表而不是生成器表达式更快:
In [8]: timeit list(chain.from_iterable(repeat(i[0], len(i)) for i in l))
1 loops, best of 3: 372 ms per loop
In [9]: timeit [i[0] for i in l for _ in range(len(i))]
1 loops, best of 3: 433 ms per loop
In [10]: timeit list(chain.from_iterable([repeat(i[0],len(i)) for i in l]))
1 loops, best of 3: 296 ms per loop
In [11]: timeit list(chain(*[[i[0]]*len(i) for i in l]))
1 loops, best of 3: 460 ms per loop
In [12]: timeit [i for x in l for i in [x[0]]*len(x)]
1 loops, best of 3: 348 ms per loop
如果你想在时间和空间之间进行折衷,那么迭代链对象一次获取一个元素:
In [18]: %%timeit
for ele in chain.from_iterable([repeat(i[0],len(i)) for i in l]):
pass
....:
1 loops, best of 3: 306 ms per lo