协慌网

登录 贡献 社区

改组对象列表

我有一个对象列表,我想对其进行洗牌。我以为可以使用random.shuffle方法,但是当列表中包含对象时,这似乎失败了。是否有一种用于改组对象的方法或解决此问题的另一种方法?

import random

class A:
    foo = "bar"

a1 = a()
a2 = a()
b = [a1, a2]

print(random.shuffle(b))

这将失败。

答案

random.shuffle应该起作用。这是一个示例,其中对象是列表:

from random import shuffle
x = [[i] for i in range(10)]
shuffle(x)

# print(x)  gives  [[9], [2], [7], [0], [4], [5], [3], [1], [8], [6]]
# of course your results will vary

请注意,随机播放可在原位运行 ,并返回 None。

当您了解到就地改组就是问题所在。我也经常遇到问题,而且似乎也常常忘记如何复制列表。解决方案使用sample(a, len(a)) ,使用len(a)作为样本大小。有关 Python 文档,请参阅https://docs.python.org/3.6/library/random.html#random.sample

这是一个使用random.sample()的简单版本, 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

我也花了一些时间来做到这一点。但是洗牌的文档非常清楚:

将列表 x 洗牌到位 ; 不返回。

所以你不应该print(random.shuffle(b)) 。相反,先执行random.shuffle(b) ,然后执行print(b)