为什么随机洗牌返回无?

为什么 random.shuffle在 Python 中返回 None

>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None

如何获得洗牌值而不是 None

117356 次浏览

random.shuffle() 更改 x列表 就位

就地修改结构的 Python API 方法通常返回 None,而不返回修改后的数据结构。

>>> x = ['foo', 'bar', 'black', 'sheep']
>>> random.shuffle(x)
>>> x
['black', 'bar', 'sheep', 'foo']

如果你想创建一个基于现有列表的 新的随机洗牌列表,其中保持现有列表的顺序,你可以使用 random.sample()和输入的完整长度:

random.sample(x, len(x))

你也可以使用 sorted()random.random()作为排序键:

shuffled = sorted(x, key=lambda k: random.random())

但这会调用排序(一个 O (N log N)操作) ,而对输入长度的采样只需要 O (N)操作(使用与 random.shuffle()相同的过程,从收缩池中交换随机值)。

演示:

>>> import random
>>> x = ['foo', 'bar', 'black', 'sheep']
>>> random.sample(x, len(x))
['bar', 'sheep', 'black', 'foo']
>>> sorted(x, key=lambda k: random.random())
['sheep', 'foo', 'black', 'bar']
>>> x
['foo', 'bar', 'black', 'sheep']

根据 医生:

将序列 x 调整到适当的位置 返回[0.0,1.0)中的随机浮点数的0参数函数; by 默认情况下,这是函数 Random ()。

>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> shuffle(x)
>>> x
['bar', 'black', 'sheep', 'foo']

说真的,为什么?

1. 效率

shuffle在适当的位置修改列表。 这很好,因为如果您不再需要原始列表,那么复制一个大列表将是纯粹的开销。

2. Python 风格

根据 蟒蛇式“显性比隐性好”原理,返回列表将是一个坏主意,因为这样一来,人们可能会认为它是一个新的 ,尽管事实上它不是。

但我不喜欢这样!

如果你的 需要一个新的列表,你将不得不写一些像

new_x = list(x)  # make a copy
random.shuffle(new_x)

非常明确。 如果您经常需要这个习惯用法,请将它包装在返回 new_x的函数 shuffled(参见 sorted)中。

这种方法也有效。

import random
shuffled = random.sample(original, len(original))

我对这个概念有过恍然大悟的时刻:

from random import shuffle
x = ['foo','black','sheep'] #original list
y = list(x) # an independent copy of the original
for i in range(5):
print shuffle(y) # shuffles the original "in place" prints "None" return
print x,y #prints original, and shuffled independent copy


>>>
None
['foo', 'black', 'sheep'] ['foo', 'black', 'sheep']
None
['foo', 'black', 'sheep'] ['black', 'foo', 'sheep']
None
['foo', 'black', 'sheep'] ['sheep', 'black', 'foo']
None
['foo', 'black', 'sheep'] ['black', 'foo', 'sheep']
None
['foo', 'black', 'sheep'] ['sheep', 'black', 'foo']