2017-01-20 52 views
2

假设我有列表列表理解的元素出现两次

l = ['a', 'c', 'b'] 

什么,我想就是这些元素出现两次,一前一后的清单,让

['a', 'a', 'c', 'c', 'b', 'b'] 

,我想以最可能的pythonic方式做到这一点。

我的一半解决方案做这样的事情

[[l[i], l[i]] for i in range(len(l))] 

这将产生

[['a', 'a'], ['c', 'c'], ['b', 'b']] 

从这里,我不得不解析(步行)的列表中删除内部列表和获得单一单子列表。

任何人都有更好的想法一次做到这一点?很显然,像l * 2这样的东西无助于['a', 'c', 'b', 'a', 'c', 'b'],我想要相邻的相同元素。

回答

4
l_2 = [item for item in l for i in range(n)] 

链接到原点:Stackoverflow: Repeating elements of a list n times

+0

选择这个,因为它似乎更优雅的一个。请注意,计时执行此操作会产生1000000个循环,最好是3:1。每个回路49μs'与@Yousaf的回答相比,它给出了'最慢的运行比最快的运行长5.32倍。这可能意味着正在缓存中间结果。 1000000循环,最好的3:每循环1.12微秒' –

+1

我估计使用更长的列表进行计时。三个要素非常短,时间并不重要。对于上面的代码,我还得到了'最慢的运行时间比最快的时间长5.41倍'。 – UpSampler

4

只使用list comprehension,你可以这样做:

[i for j in my_list for i in [j]*2] 

输出:

>>> my_list = ['a', 'c', 'b'] 
>>> [i for j in my_list for i in [j]*2] 
['a', 'a', 'c', 'c', 'b', 'b'] 
3

可以zip列表针对其自身,然后在列表理解平整。

>>> [i for j in zip(l,l) for i in j] 
['a', 'a', 'c', 'c', 'b', 'b'] 
2

可以使用zip功能

l = ['a', 'c', 'b'] 
a = [i for j in zip(l,l) for i in j] 
print(a) 

输出

['a', 'a', 'c', 'c', 'b', 'b'] 
1

更普遍的:

def ntimes(iterable, times=2): 
    for elt in iterable: 
     for _ in range(times): 
      yield elt 
1

这里是没有列表理解一个简短的解决方案,采用直观的想法l*2

sorted(l*2, key=l.index) 
#['a', 'a', 'c', 'c', 'b', 'b'] 
1

如果你喜欢功能性的方法,你可以这样做:

from itertools import chain, tee 

l = ['a', 'c', 'b'] 
n = 2 

list(chain.from_iterable(zip(*tee(l, n)))) 

虽然这可能无法像其他答案一样快,但它可以轻松地用于任意迭代(特别是在它们正在流行或者当您不知道何时结束时),方法是省略list()

(请注意,一些其他的答案也可以通过由发电机表达式来替换他们的列表理解可以适用于任意iterables。)