我想创建一个类似于
的数组[0, 0, 0, 1, 1 , 1, 2, 2, 2, . . .etc]
或
[4,4,4,4,5,5,5,5,6,6,6,6,... 。 。等]
有类似
的内容segments = [i for i in range(32)]
将使
[ 1, 2, 3, 4, 5, . . . etc]
有些方法我可以调用3个独立的i in range(32)
集,但我希望通过只调用一次来节省计算。
制作像
这样的数组的计算效率最高,编程最优雅的方法是什么[0, 0, 0, 1, 1 , 1, 2, 2, 2, . . .etc]
答案 0 :(得分:7)
在itertools.chain
iterables上使用itertools.repeat
:
import itertools
result = list(itertools.chain.from_iterable(itertools.repeat(i,3) for i in range(32)))
print(result)
结果:
[0,0,0,1,1,1,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7, 7,8,8,9,9,9,10,10,10,11,11,11,12,12,12,13,13,13,14,14,14,15,15,15, 16,16,16,17,17,17,18,18,18,19,19,19,20,20,20,21,21,21,22,22,22,23,23,23,24, 24,24,25,25,25,26,26,26,27,27,27,28,28,28,29,29,29,30,30,30,31,31,31]
这种技术避免了创建中间列表并最小化纯python循环(一个python循环总计,使用map
可以删除最后一个,但这需要lambda
case,增加了一个函数调用。)
编辑:让我们回答这个问题并Ted's answer
import itertools,time
n=1000000
start_time = time.time()
for _ in range(n):
list(itertools.chain.from_iterable(itertools.repeat(i,3) for i in range(32)))
print("itertools",time.time() - start_time)
start_time = time.time()
for _ in range(n):
[i for i in range(32) for _ in range(3)]
print("flat listcomp",time.time() - start_time)
结果:
itertools 10.719785928726196
flat listcomp 13.869723081588745
因此使用itertools
而不是list comprension的速度提高约30%(python 3.4,windows)
注意:
少量重复会在内循环中产生大量itertools.repeat
次调用,因此在3次重复的情况下,执行NickA suggests的速度会更快:
list(itertools.chain.from_iterable((i,)*3 for i in range(32)))
(上述替补席上7秒对10分)
numpy
解决方案更快(约1.5秒),如果您可以使用numpy
:
import numpy as np
np.arange(32).repeat(3) # credits: liliscent
答案 1 :(得分:4)
只需在列表推导中使用嵌套循环。
segments = [i for i in range(32) for _ in range(3)]
输出:
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31]
答案 2 :(得分:2)
使用场地划分:
userid
示例输出:
then
如果你真的想要一个def repeated_value_list(repeats, start, stop=None):
if stop is None:
start, stop = 0, start
return [x//repeats for x in range(start*repeats, stop*repeats)]
数组,那就更有效了,因为广播可以在不理解的情况下进行分配:
>>> repeated_value_list(3, 5)
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]
>>> repeated_value_list(3, 4, 10)
[4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9]
输出:
numpy
答案 3 :(得分:1)
如果我们有[(0, 0, 0), (1, 1, 1), …]
,我们只需要压扁它:
[elem for sublst in lst for elem in sublst]
我们如何做到这一点?好吧,如果我们有三个单独的序列[0, 1, 2, …]
,我们可以zip
将它们放在一起:
lst = zip(r1, r2, r3)
这三个序列只是range(32)
:
lst = zip(range(32), range(32), range(32))
...或者,如果你想要它是动态的而不是完全是32和3:
lst = zip(*(range(count) for _ in range(reps)))
无论哪种方式,你都可以把它组合成一个单行:
[elem for sublst in zip(*(range(count) for _ in range(reps))) for elem in sublst]
然后你可以简化:
[elem for elem in range(count) for _ in range(reps)]
答案 4 :(得分:0)
您可以使用itertools.chain.from_iterable
:
>>> list(itertools.chain.from_iterable([[i]*3 for i in range(32)]))
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31]