为什么要用Pythonrandom.shuffle
返回None
?
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
我如何获得改组后的值而不是None
?
为什么要用Pythonrandom.shuffle
返回None
?
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
我如何获得改组后的值而不是None
?
Answers:
random.shuffle()
更改x
列表到位。
在原位更改结构的Python API方法通常返回None
,而不是修改后的数据结构。
如果要基于现有列表创建新的随机混排列表,并按顺序保留现有列表,则可以使用random.sample()
输入的完整长度:
x = ['foo', 'bar', 'black', 'sheep']
random.sample(x, len(x))
您还可以将sorted()
withrandom.random()
用于排序键:
shuffled = sorted(x, key=lambda k: random.random())
但这会调用排序(O(NlogN)操作),而采样到输入长度仅需要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']
key
函数真的可以保证吗?如果比较不一致,则某些快速排序算法会失败。我可以看到这两种方式都有效,具体取决于实现方式(decorate-sort-undecorate只需key
在每个元素上应用一次,因此定义明确)。
key
可调用对象进行排序时,Python使用decorate-sort-undecorate 。是的,因此可以保证每个值都被赋予一次随机键。
shuffle
修改列表到位。这很好,因为如果您不再需要原始列表,则复制大列表将是纯开销。
根据pythonic样式的“显式胜于隐式”原则,返回列表将是一个坏主意,因为那时人们可能认为它是一个新列表,尽管实际上并非如此。
如果您确实需要新的清单,则必须编写类似
new_x = list(x) # make a copy
random.shuffle(new_x)
这是很明确的。如果您经常需要该惯用法,请将其包装在一个返回return的函数中shuffled
(请参阅参考资料sorted
)new_x
。
我很喜欢这个概念,像这样:
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']