Python 如何生成数字序列的随机列表?

Python 如何生成数字序列的随机列表?,python,python-3.x,random,Python,Python 3.x,Random,我想要一个函数来生成一个长度为n的列表,其中包含一个0到1之间的算术数字序列,但以随机顺序排列 例如,对于函数 def randSequence(n): ... return myList 返回 [0.5, 0.3, 0.9, 0.8, 0.6, 0.2, 0.4, 0.0, 0.1, 0.7] [0.4, 0.0, 0.2, 0.8, 0.6] 及 返回 [0.5, 0.3, 0.9, 0.8, 0.6, 0.2, 0.4, 0.0, 0.1, 0.7] [0.4, 0

我想要一个函数来生成一个长度为n的列表,其中包含一个0到1之间的算术数字序列,但以随机顺序排列

例如,对于函数

def randSequence(n):
    ...
    return myList
返回

[0.5, 0.3, 0.9, 0.8, 0.6, 0.2, 0.4, 0.0, 0.1, 0.7]
[0.4, 0.0, 0.2, 0.8, 0.6]

返回

[0.5, 0.3, 0.9, 0.8, 0.6, 0.2, 0.4, 0.0, 0.1, 0.7]
[0.4, 0.0, 0.2, 0.8, 0.6]
目前,我有它,它在一个循环中生成数字序列,并在另一个循环中随机化,如下所示:

def randSequence(n):
    step = 1 / n
    setList = []
    myList = []
    for i in range(n):
        setList.append(i * step)
    for i in range(n):
        index = random.randint(0, len(setList) - 1)
        myList.append(setList.pop(index))
    return myList

不幸的是,这个解决方案很慢,特别是对于大的数字(比如n>1000000)。是否有更好的方法编写此代码,或者更好的方法,是否有一个函数可以为我完成此任务?

@HeapOverflow建议将第二个循环替换为shuffle函数:

def randSequence(n):
    step = 1 / n
    myList = []
    for i in range(n):
        myList.append(i * step)
    random.shuffle(myList)
    return myList

这比以前快了一个数量级。根据过去的经验,我怀疑列表上的pop函数相当慢,是第二个循环中的主要瓶颈。

首先,我想指出,代码性能差的主要原因是由于以下几行:

myList.append(setList.pop(index))
列表中间的时间复杂度
list.pop
大致为
O(n)
,因为从列表中间弹出会迫使Python移动大量内存。这使得净复杂性
O(n^2)
。您可以通过就地更改来大幅提高性能,例如:

def randSequenceInplace(n):
    'a.k.a. Fisher-Yates'
    step = 1 / n
    lst = [step * i for i in range(n)]
    for i in range(n-1):
        index = random.randint(i, n - 1)
        lst[i], lst[index] = lst[index], lst[i]
        # myList.append(setList.pop(index))
    return lst

为了完整性,您可以使用矢量化的
numpy
解决方案,或者使用前面提到的
random.shuffle
来获得更好的性能。时间:

n = 10**6
%time randSequence(n)
# CPU times: user 1min 22s, sys: 33 ms, total: 1min 22s
# Wall time: 1min 22s
%time randSequenceInplace(n)
# CPU times: user 1.33 s, sys: 1.91 ms, total: 1.33 s
# Wall time: 1.33 s
%timeit np.random.permutation(n) / n
# 10 loops, best of 3: 22.4 ms per loop

为什么不使用
shuffle
函数呢?对于大型
n
,您最好使用
numpy.random
。试试
numpy.random.random
@AccLok,它不能保证算术级数属性。@HeapOverflow shuffle速度要快一点!谢谢你。即使如此,我还是很好奇,是否已经有一些函数为你做了这件事,比如在生成序列的过程中,n的数量级是多少?因为你的原稿是二次的,而这个是线性的,这取决于n。也许我的措辞不好。这个想法是,移动
O(n)
内存位直观上比在
O(n)
内存位上迭代更糟糕,因此是“附加”部分。