我有一个对象的列表,我想对它们进行洗牌。我想我可以使用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
请注意,shuffle在**地方工作,并返回None。
正如你所了解到的原地洗牌是问题所在。
我也经常出现问题,似乎也经常忘记如何复制一个列表。
使用sample(a, len(a))
是解决办法,用len(a)
作为样本大小。
参见https://docs.python.org/3.6/library/random.html#random.sample,了解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
我也是花了一些时间才弄明白的。 但洗牌的文档非常清晰。
shuffle list x *in place; 返回None。
所以你不应该print(random.shuffle(b))
。
而应该做random.shuffle(b)
,然后print(b)
。
如果你恰好已经在使用numpy(在科学和金融应用中非常流行),你可以省去一个导入。
import numpy as np
np.random.shuffle(b)
print(b)
http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.shuffle.html
如果您有多个列表,您可能希望先定义换行法(洗牌列表/重新排列列表中的项目的方式),然后将其应用于所有列表。
import random
perm = list(range(len(list_one)))
random.shuffle(perm)
list_one = [list_one[index] for index in perm]
list_two = [list_two[index] for index in perm]
如果你的列表是numpy数组,那就更简单了。
import numpy as np
perm = np.random.permutation(len(list_one))
list_one = list_one[perm]
list_two = list_two[perm]
我创建了一个小工具包 mpu
,其中有 consistent_shuffle
函数。
import mpu
# Necessary if you want consistent results
import random
random.seed(8)
# Define example lists
list_one = [1,2,3]
list_two = ['a', 'b', 'c']
# Call the function
list_one, list_two = mpu.consistent_shuffle(list_one, list_two)
请注意,mpu.consistent_shuffle
可以接受任意数量的参数。
所以你也可以用它来洗牌三个或更多的列表。
在某些情况下,当使用numpy数组时,使用random.shuffle
会在数组中产生重复的数据。
另一种方法是使用numpy.random.shuffle
。
如果你已经在使用numpy了,这是比通用的random.shuffle
更可取的方法。
[numpy.random.shuffle][1] 。
实例
>>> import numpy as np
>>> import random
使用random.shuffle
。
>>> foo = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> foo
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> random.shuffle(foo)
>>> foo
array([[1, 2, 3],
[1, 2, 3],
[4, 5, 6]])
使用numpy.random.shuffle
。
>>> foo = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> foo
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> np.random.shuffle(foo)
>>> foo
array([[1, 2, 3],
[7, 8, 9],
[4, 5, 6]])
[1]: https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.shuffle.html
'print func(foo)'。 将打印'func'的返回值。 调用'foo'时,将打印'func'的返回值。 'shuffle'的返回值。 然而,它的返回类型是 None,因为列表将被原地修改,因此它不会打印任何内容。 解决办法是:{{{5782262}}。
# shuffle the list in place
random.shuffle(b)
# print it
print(b)
如果你更喜欢函数式编程风格,你可能会想做下面的包装函数。
def myshuffle(ls):
random.shuffle(ls)
return ls
import random
class a:
foo = "bar"
a1 = a()
a2 = a()
a3 = a()
a4 = a()
b = [a1,a2,a3,a4]
random.shuffle(b)
print(b)
shuffle
到位了,所以不打印结果,也就是None
,而是打印列表。
""" to shuffle random, set random= True """
def shuffle(x,random=False):
shuffled = []
ma = x
if random == True:
rando = [ma[i] for i in np.random.randint(0,len(ma),len(ma))]
return rando
if random == False:
for i in range(len(ma)):
ave = len(ma)//3
if i < ave:
shuffled.append(ma[i+ave])
else:
shuffled.append(ma[i-ave])
return shuffled
你可以建立一个函数,将一个 list 作为参数并返回一个洗牌版的 list。
from random import *
def listshuffler(inputlist):
for i in range(len(inputlist)):
swap = randint(0,len(inputlist)-1)
temp = inputlist[swap]
inputlist[swap] = inputlist[i]
inputlist[i] = temp
return inputlist