为什么在 Python中random.shuffle
返回?None
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
如何获得洗牌后的价值,而不是None
?
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()
withrandom.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']
这种方法也有效。
import random
shuffled = random.sample(original, len(original))
shuffle
修改列表。这很好,因为如果您不再需要原始列表,复制一个大列表将是纯粹的开销。
根据pythonic 风格的“显式优于隐式”原则,返回列表将是一个坏主意,因为这样可能会认为它是一个新列表,但实际上并非如此。
如果您确实需要一个新列表,则必须编写类似的内容
new_x = list(x) # make a copy
random.shuffle(new_x)
这是非常明确的。如果您经常需要这个习惯用法,请将其包装在一个返回的函数中shuffled
(请参阅 参考资料) 。sorted
new_x
根据文档:
将序列 x 打乱到位。可选参数 random 是一个 0 参数函数,返回 [0.0, 1.0) 中的随机浮点数;默认情况下,这是函数 random()。
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> shuffle(x)
>>> x
['bar', 'black', 'sheep', 'foo']
对于这样的概念,我有我的 aha 时刻:
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']