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