对象列表的随机排序

935 投票
26 回答
1135981 浏览
提问于 2025-04-15 12:09

我该怎么打乱一个对象列表呢?我试过用 random.shuffle

import random

b = [object(), object()]

print(random.shuffle(b))

但是它输出的是:

None

26 个回答

94

关于random.shuffle的说明里提到,它会

在原地打乱序列x的顺序。

不要这样做:

print(random.shuffle(xs))  # WRONG!

而是应该这样做:

random.shuffle(xs)
print(xs)
138

你已经了解到,原地洗牌是个问题。我自己也经常遇到这个问题,而且常常忘记怎么复制一个列表。使用 sample(a, len(a)) 是解决办法,这里 len(a) 是作为样本大小的。你可以查看 这个链接,里面有Python的相关文档。

下面是一个简单的例子,使用 random.sample() 来返回一个新的洗牌结果列表。

import random

a = range(5)
b = random.sample(a, len(a))
print a, b, "two list same:", a == b
# print: [0, 1, 2, 3, 4] [2, 1, 3, 4, 0] two list same: False

# The function sample allows no duplicates.
# Result can be smaller but not larger than the input.
a = range(555)
b = random.sample(a, len(a))
print "no duplicates:", a == list(set(b))

try:
    random.sample(a, len(a) + 1)
except ValueError as e:
    print "Nope!", e

# print: no duplicates: True
# print: Nope! sample larger than population
1480

random.shuffle 这个功能应该可以用。这里有个例子,里面的对象是列表:

from random import shuffle

x = [[i] for i in range(10)]
shuffle(x)
print(x)

# print(x)  gives  [[9], [2], [7], [0], [4], [5], [3], [1], [8], [6]]

需要注意的是,shuffle就地操作的,也就是说它直接在原来的地方改变了列表,而不是返回一个新的列表,它的返回值是 None

在Python中,一般来说,可变对象可以传递给函数,当一个函数改变了这些对象时,通常的做法是返回 None(而不是返回被改变后的对象)。

撰写回答