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

Python 根据长度重复列表列表的第一个元素,python,list,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]] 尽管如此,它仍然返回列表列表,而不是

我有一个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]]
尽管如此,它仍然返回列表列表,而不是平面列表。因此,我试图找出基于上述标准创建平面列表的最快方法


更新:我想要执行最快的方法,因为列表很长

您可以这样做

>>> [i[0] for i in l for _ in range(len(i))]
[1, 1, 1, 4, 5, 5, 7, 7, 7, 7]
>>> 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]
您可以使用将结果展平

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\u 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

其余的答案都很好。下面是一个使用and的备选答案



1以便您可以学习新的python模块。

使用
itertools。使用
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

@巴尔加夫罗,谢谢!不幸的是,仍然有2票反对(这些家伙现在变得非常快了!:我想要最快的执行方法,因为列表很长,希望其他答案不会被抛弃!我添加了更新,但原始帖子明确提到我的解决方案很慢。编辑你的答案如何要考虑到这一点吗?Brother do注意到这是为了整个社区。因此,我们的回答也考虑到了未来的用户。但记住只接受你认为最好的答案。:)。(几年后会有很多答案)你真的需要所有元素同时出现吗?@Bhargav:我同意你的观点。不是我投了反对票,因为我也重视替代答案和教育性答案。使用内置的答案很棒。建议在
print res
JIC中的
res
周围放上括号,OP使用的是py3。
chain.from\u iterable
通常更快
itertools.chain.from\u iterable([[i[0]]*len(i)表示l中的i])
也会做同样的事情。这基本上就是
chain*
所做的,但我总是发现使用
from\u iterable
是可行的faster@BhargavRao:谢谢您对打印功能的建议。@TanveerAlam Np。随时记住这条建议,不管是什么小要求。请您尝试一下
timeit
并对结果进行回复,好吗?(如果我在comp的话,我会自己做的)抱歉打扰你:(@BhargavRao,别担心,不过我想你不会喜欢结果的!我猜事情已经结束了1000ms@BhargavRao,您可能可以删除
m
;)嘿!不如我像你说的那样去掉
m
,然后把
m
放在那里?但是如果警察试过那种方法,他会非常生气的!我最好在这里添加一个免责声明;)如前所述,就时间复杂性而言,这是所有答案中最糟糕的!所以要小心;)[林中树的叶对应树中叶]=林中树的叶对应树中叶,返回叶
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