2013-03-14 81 views
3

說我有這個名單:如何增加和填充python列表的大小?

[1,2,3,4] 

,我想:

[1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4] 

什麼是這樣做的最佳方式?

我目前的方法是創建一個新的列表:

x = [1,2,3,4] 
y = [[n]*4 for n in x] 

這給:

[[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]] 

這似乎接近,但沒有雪茄......誰能幫助?

回答

13
>>> x = [1,2,3,4] 
>>> [n for n in x for _ in range(4)] 
    [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4] 

 

itertools.repeat確實是語義上更清潔,謝謝,史蒂芬:

from itertools import repeat 
[repeated for value in x for repeated in repeat(value, 4)] 
+0

這種簡單性很難擊敗(+1) – NPE 2013-03-14 15:10:42

+2

+1。我最喜歡這個,但是如果我要使用itertools解決方案,我會使用'itertools.repeat':'[n2 for n in x for n2 in repeat(n,4)]''。 – 2013-03-14 15:20:11

+0

另一個'itertools'解決方案:'list(chain(* izip(* repeat(x,4))))',但現在我們正在陷入一些難以精神分析的東西。 – 2013-03-14 15:43:48

0

簡單的方法:

y = [n for n in x*4] 

這將返回[1, 2, 3, 4, 1, 2, 3, 4, ...]

要按照你想要的順序,你可以做x = sorted(x)y = sorted([n for n in x*4])

這與y = sorted(x*4)類似。

最好的方法是做@Pavel Anossov怎麼說:

y = [n for n in x for _ in range(4)] 

這是最好的,因爲它會爲任何序列,而sorted(x*4)工作,不守秩序,僅適用於原分類列表。

+0

那麼,這隻適用於排序列表。確實解決這個特定的解決方案,但不是通用的,因此不可重用,這使得它很無用。 – Qwerty 2013-03-14 16:03:26

2

您可以使用itertools.chain()chain.from_iterable()到(你的情況y)壓平列表的列表:

In [23]: lis=[1,2,3,4] 

In [24]: from itertools import chain 

In [31]: y = list(chain(*([n]*4 for n in lis))) 

In [32]: y 
Out[32]: [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4] 

一些性能比較:

In [25]: x=[1,2,3,4]*1000 #can't use more than 1000 due to limited RAM 

In [26]: %timeit list(chain(*([n]*1000 for n in x))) 
1 loops, best of 3: 196 ms per loop 

In [27]: %timeit list(chain.from_iterable(([n]*1000 for n in x))) 
1 loops, best of 3: 177 ms per loop 

In [29]: %timeit [n for n in x for _ in xrange(1000)] 
1 loops, best of 3: 388 ms per loop 

#three more solutions;from @Steven Rumbalski 

In [28]: %timeit [repeated for value in x for repeated in repeat(value,1000)] 
1 loops, best of 3: 344 ms per loop 

In [30]: %timeit list(chain.from_iterable(izip(*repeat(x,1000)))) 
1 loops, best of 3: 204 ms per loop 

In [31]: %timeit list(chain(*izip(*repeat(x,1000)))) 
1 loops, best of 3: 238 ms per loop 
+0

+1我不知道'reduce'函數是如何比較的(就像@nvlass的答案)? – atomh33ls 2013-03-14 15:58:23

+0

@ atomh33ls'reduce()'與這些替代方法相比非常慢。 – 2013-03-14 16:05:49

+1

請注意,這些方法在小列表上的比較非常不同。 – 2013-03-14 18:55:04

1

您可以隨時使用reduce

reduce(lambda x, y: x+y, [[n]*4 for n in x]) 
+0

我剛剛發現:'reduce(list .__ add __,y)'這似乎也起作用。 – atomh33ls 2013-03-14 15:19:10

+1

@ atomh33ls確實:) list .__ add__是在列表中使用'+'時所謂的 – nvlass 2013-03-14 15:21:02

+2

'operator.add'比lambda快。 – 2013-03-14 15:35:08

1

這裏是我會做。

x = [1,2,3,4] 
y = x*4 
y.sort() 

簡單和整潔。