Why does random.shuffle return None?
为什么
1 2 3 4 | >>> x = ['foo','bar','black','sheep'] >>> from random import shuffle >>> print shuffle(x) None |
如何得到洗牌后的值而不是
就地改变结构的 Python API 方法通常返回
1 2 3 4 | >>> x = ['foo', 'bar', 'black', 'sheep'] >>> random.shuffle(x) >>> x ['black', 'bar', 'sheep', 'foo'] |
如果您想根据现有列表创建一个新的随机打乱列表,其中现有列表保持有序,您可以使用
1 | random.sample(x, len(x)) |
您也可以使用
1 | shuffled = sorted(x, key=lambda k: random.random()) |
但这会调用排序(O(N log N) 操作),而对输入长度的采样只需要 O(N) 操作(使用与
演示:
1 2 3 4 5 6 7 8 | >>> 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'] |
这个方法也行。
1 2 | import random shuffled = random.sample(original, len(original)) |
为什么,真的?
1.效率
这很好,因为如果您不再需要原始列表,复制一个大列表将是纯粹的开销。
2. Pythonic风格
根据pythonic风格的"显式优于隐式"原则,返回列表是一个坏主意,因为这样可能会认为它是一个新的,但实际上并非如此。
但我不喜欢这样!
如果你确实需要一个新的列表,你将不得不写类似
1 2 | new_x = list(x) # make a copy random.shuffle(new_x) |
非常明确。
如果您经常需要这个习惯用法,请将其package在返回
的函数
根据文档:
Shuffle the sequence x in place. The optional argument random is a
0-argument function returning a random float in [0.0, 1.0); by
default, this is the function random().
1 2 3 4 5 | >>> x = ['foo','bar','black','sheep'] >>> from random import shuffle >>> shuffle(x) >>> x ['bar', 'black', 'sheep', 'foo'] |
我对这个概念有过这样的感觉:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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'] |