list - python 重复索引列表

  显示原文与译文双语对照的内容
82 3

我正在尝试创建一个从 0m - 1的索引列表,长度为 n 。 至此,我已经达到了如下目的:


import numpy as np


m = 7


n = 12


indices = [np.mod(i, m) for i in np.arange(n)]



这将导致以下结果:


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



有更快速的方法来实现这个?

感谢你的建议。

时间: 原作者:

142 5

因为你要求尽可能快的速度,所以最好提供一些测试时间。 因此,我使用 timeit 模块测试了大部分已经发布的代码片段。

快速定义的函数,便于调用时间。


def list_comp(m, n):


 return [np.mod(i, m) for i in np.arange(n)]



def leftover(m, n):


 nb_cycles = n//m


 leftover = n-m*nb_cycles


 indices = list(range(m))*nb_cycles + list(range(leftover))



def islice_cycle(m, n):


 return list(islice(cycle(range(m)), n))



def npmod(m, n):


 return mod(np.arange(m), n)



def resized(m, n):


 return np.resize(np.arange(m), n)



测试:


timer = timeit.Timer(stmt="function_name(7, 12)", globals=globals()).repeat(repeat=100, number =10000)


print(f'Min: {min(timer):.6}s,n Avg: {np.average(timer):.6}s')



结果


| Function | Minimum | Average | 


|:---------------|------------:|:------------:| 


| list_comp | 0.156117s | 0.160433s | 


| islice_cycle | 0.00712442s | 0.00726821s | 


| npmod | 0.0118933s | 0.0123122s | 


| leftover | 0.00943538s | 0.00964464s | 


| resized | 0.0818617s | 0.0851646s | 



使用 islicecycle是迄今为止最快的。

其他答案的速度较慢。

116 0

你可以使用 islice + cycleitertools 中:


from itertools import islice, cycle



print(list(islice(cycle(range(7)), 12)))


# [0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4]



原作者:
120 0

python只需使用list comprehension将往返数据删除。 从numpy获得良好的速度就是确保你的循环保持在numpy内,而不是在python本身内循环。


np.mod(np.arange(n), m)



这是唯一的numpythonically正确答案,从意义上说,python 中的所有循环都是避免的。

原作者:
...