根据长度重复列表列表的第一个元素

时间:2015-03-11 13:57:21

标签: python list

我有一个列表的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]]

虽然,这仍然会返回列表而不是平面列表。所以,我试图找出基于上述标准创建该平面列表的最快方法。

更新:由于列表很长,我想要性能最快的方法

5 个答案:

答案 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)

其余答案非常好。以下是使用mapreduce

替代答案 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.repeatchain使用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