2013-03-14 82 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() 

简单和整洁。