2011-08-25 85 views
4

所以每个人都知道我能得到号码列表与range像这样:python范围()与重复?

>>> range(5) 
[0, 1, 2, 3, 4] 

如果我想,说,每个数字的3份,我可以使用:

>>> range(5)*3 
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4] 

不过是有没有办法使用range重复这样的副本呢?

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

有没有一个快速和优雅的内置方式来做到这一点? sorted(range(5)*3)具有不必要的n * log(n)复杂性,并且[x//3 for x in range(3*5)]有效,但似乎是对//操作的滥用。

+2

即使你说你不想要它,排序(范围(5)* 3)对我来说看起来很优雅:)) – Habbie

回答

11

你可以这样做:

>>> [i for i in range(5) for _ in range(3)] 
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4] 

range(3)部分应该与你重复的次数来代替......

BTW,您应该使用发电机


只是使它更清楚的是,_是一个你不关心的东西的变量名(任何名字都是允许的)。

这个列表解析使用嵌套for循环和就像是:

for i in range(5): 
    for j in range(3): 
     #your code here 
+0

我喜欢它!如果你能解释这个神秘的列表技巧是如何工作的,我会接受这个答案。我在交互式python中使用了'_'来引用前面的输出,它是否与此有关? – wim

+1

在代码中使用'_'来表示你不关心变量的含义。我只想循环3次,但不关心索引...这是一个约定,认为 – JBernardo

+3

我说的发电机是:'(我为xrange(5)为我在xrange(3)j)' – JBernardo

7

试试这个:

itertools.chain.from_iterable(itertools.repeat(x, 3) for x in range(5)) 
-2
import itertools 
[x for tupl in itertools.izip(*itertools.tee(range(0,5),3)) for x in tupl] 

或者:

[x for tupl in zip(range(0,5), range(0,5), range(0,5)) for x in tupl] 
+2

你吓坏了吗?我笑了 – 2011-08-25 05:45:25

-2

我喜欢保持它很简单:)

>>> sorted(list(range(5)) * 3) 
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4] 
+0

哦,有人已经提到过... – pawroman

4
from itertools import chain, izip 
list(chain(*izip(*[xrange(5)]*3))) 

给人

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

留出榜单,你有一台发电机。

编辑:或者更好(遗漏了一个函数调用izip):

list(chain(*([x]*3 for x in xrange(5)))) 
1
>>> from itertools import chain, izip, tee 
>>> list(chain.from_iterable(izip(*tee(range(5), 3)))) 
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4] 
1

使用另一种方法清凉的迭代器:

>>> from collections import Counter 
>>> Counter(range(5) * 3).elements()