关于python:为什么random.shuffle返回None?

Why does random.shuffle return None?

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

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

如何得到洗牌后的值而不是 None


random.shuffle() 更改 x 列表。

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

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

如果您想根据现有列表创建一个新的随机打乱列表,其中现有列表保持有序,您可以使用 random.sample() 与输入的完整长度:

1
random.sample(x, len(x))

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

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

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

演示:

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.效率

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

2. Pythonic风格

根据pythonic风格的"显式优于隐式"原则,返回列表是一个坏主意,因为这样可能会认为它是一个新的,但实际上并非如此。

但我不喜欢这样!

如果你确实需要一个新的列表,你将不得不写类似

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

非常明确。
如果您经常需要这个习惯用法,请将其package在返回 new_x.

的函数 shuffled(参见 sorted)中


根据文档:

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']