洗牌对象列表

utd*_*ant 723 python random shuffle list

我在Python中有一个对象列表,我想要将它们混洗.我以为我可以使用该random.shuffle方法,但当列表是对象时,这似乎失败了.是否有一种方法可以改变对象或其他方式?

import random

class A:
    foo = "bar"

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

print(random.shuffle(b))
Run Code Online (Sandbox Code Playgroud)

这将失败.

tom*_*m10 1184

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
Run Code Online (Sandbox Code Playgroud)

请注意,shuffle 在适当的位置工作,并返回None.

  • 是否有一个选项不会改变原始数组但返回一个新的混洗数组? (7认同)
  • @seokhonlee用于加密安全随机性,使用`来自随机导入SystemRandom`; 添加`cryptorand = SystemRandom()`并将第3行更改为`cryptorand.shuffle(x)` (6认同)
  • @CharlieParker:我不知道.你可以使用`random.sample(x,len(x))`或者只是制作副本和`shuffle`.对于有类似问题的`list.sort`,现在有`list.sorted`,但是`shuffle`没有类似的变体. (4认同)
  • 使用克隆创建新列表 (2认同)

Ted*_*Ted 110

当你了解到就地改组就是问题所在.我也经常遇到问题,而且似乎也经常忘记如何复制列表.使用sample(a, len(a))是解决方案,使用len(a)样本大小.有关Python文档,请参阅https://docs.python.org/3.6/library/random.html#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
Run Code Online (Sandbox Code Playgroud)

  • 是否有一个选项不会改变原始数组但返回一个新的打乱数组? (2认同)

Oha*_*hen 52

我也花了一些时间来做到这一点.但是shuffle的文档很清楚:

洗牌清单x 到位 ; 返回无.

所以你不应该print(random.shuffle(b)).相反,这样做random.shuffle(b),然后print(b).


小智 39

#!/usr/bin/python3

import random

s=list(range(5))
random.shuffle(s) # << shuffle before print or assignment
print(s)

# print: [2, 4, 1, 3, 0]
Run Code Online (Sandbox Code Playgroud)


fan*_*ous 28

如果您恰好使用numpy(非常受科学和金融应用程序欢迎),您可以节省自己的导入.

import numpy as np    
np.random.shuffle(b)
print(b)
Run Code Online (Sandbox Code Playgroud)

http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.shuffle.html

  • @VanBantam 在“random”模块中,有“seed()”函数,可用于创建可重现的输出(https://docs.python.org/3/library/random.html#random.seed) (4认同)
  • 我喜欢这个答案的地方是我可以控制 numpy 中的随机种子。我敢打赌,在随机模块中有一种方法可以做到这一点,但现在对我来说并不明显......这意味着我需要阅读更多内容。 (2认同)

Dan*_*enc 24

>>> import random
>>> a = ['hi','world','cat','dog']
>>> random.shuffle(a,random.random)
>>> a
['hi', 'cat', 'dog', 'world']
Run Code Online (Sandbox Code Playgroud)

这对我来说可以.确保设置随机方法.

  • 第二个参数默认为random.random.把它放在外面是完全安全的. (4认同)
  • @alvas random.shuffle(a)不返回任何内容,即返回None.所以你必须检查一个不返回的值. (3认同)

Mar*_*oma 13

如果您有多个列表,则可能需要先定义排列(将列表重新排列/重新排列列表中的项目的方式),然后将其应用于所有列表:

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]
Run Code Online (Sandbox Code Playgroud)

Numpy/Scipy

如果您的列表是numpy数组,则更简单:

import numpy as np

perm = np.random.permutation(len(list_one))
list_one = list_one[perm]
list_two = list_two[perm]
Run Code Online (Sandbox Code Playgroud)

MPU

我创建了一个小实用程序包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)
Run Code Online (Sandbox Code Playgroud)

请注意,mpu.consistent_shuffle它采用任意数量的参数.所以你也可以随便洗三个或更多列表.


Jef*_*eff 9

from random import random
my_list = range(10)
shuffled_list = sorted(my_list, key=lambda x: random())
Run Code Online (Sandbox Code Playgroud)

对于要交换排序功能的某些应用程序,此替代方法可能很有用.

  • 由于 Timsort 的稳定性,这不会真正随机分配值。(具有相同键的值保留其原始顺序。) 编辑:我认为这无关紧要,因为与 64 位浮点数发生冲突的风险非常小。 (2认同)

Gor*_*ean 9

在某些情况下,使用numpy数组时,使用数组中random.shuffle创建的重复数据.

另一种方法是使用numpy.random.shuffle.如果你已经使用numpy,这是优于泛型的首选方法random.shuffle.

numpy.random.shuffle

>>> import numpy as np
>>> import random
Run Code Online (Sandbox Code Playgroud)

使用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]])
Run Code Online (Sandbox Code Playgroud)

使用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]])
Run Code Online (Sandbox Code Playgroud)


小智 6

当使用'foo'调用时,'print func(foo)'将打印'func'的返回值.'shuffle'但是返回类型为None,因为列表将被修改到位,因此它不会打印任何内容.解决方法:

# shuffle the list in place 
random.shuffle(b)

# print it
print(b)
Run Code Online (Sandbox Code Playgroud)

如果您更喜欢函数式编程风格,您可能需要创建以下包装函数:

def myshuffle(ls):
    random.shuffle(ls)
    return ls
Run Code Online (Sandbox Code Playgroud)

  • 由于这会传递对列表的引用,因此原始文件会被修改.您可能希望在使用[deepcopy](http://docs.python.org/2/library/copy.html)进行混洗之前复制列表 (2认同)

mal*_*rbo 5

可以定义一个调用的函数shuffledsort与 vs相同sorted

def shuffled(x):
    import random
    y = x[:]
    random.shuffle(y)
    return y

x = shuffled([1, 2, 3, 4])
print x
Run Code Online (Sandbox Code Playgroud)


小智 5

对于单行代码,请使用random.sample(list_to_be_shuffled, length_of_the_list)示例:

import random
random.sample(list(range(10)), 10)
Run Code Online (Sandbox Code Playgroud)

输出:[2、9、7、8、3、0、4、1、6、5]


归档时间:

查看次数:

898645 次

最近记录:

6 年 前