2013-07-15 5 views
45

Почему random.shuffle возвращение None в python?Почему random.shuffle возвращает None?

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

Как получить перетасованное значение вместо None?

+0

не случайное значение, но случайное перетасовка списка. – alvas

+2

Связано: [sort() и функции reverse() не работают] (http://stackoverflow.com/q/16460616) –

ответ

71

random.shuffle() изменяет список xна месте.

Методы API Python, которые изменяют структуру на месте, обычно возвращают None, а не модифицированную структуру данных.

Если вы хотите создать новый случайным образом перемешиваются список на основе уже существующего, где существующий список хранится в порядке, вы могли бы использовать random.sample() с полной длины входа:

x = ['foo', 'bar', 'black', 'sheep'] 
random.sample(x, len(x))  

Вы также можете использовать sorted() с random.random() для сортировки ключа:

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

, но это вызывает сортировку (уплотнительная (NlogN) операция), пробуя на inpu t длина принимает только операции 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'] 
+0

Как насчет '.pop()'? Это удаляет данный индекс из списка и возвращает элемент, или мне что-то не хватает – TerryA

+0

@Haidro: sure, '.pop()' явно документируется как возвращающий удаленный элемент. Скорректирована формулировка. –

+2

Действительно ли используется функция «ключ» с произвольной оценкой? Некоторые быстрые алгоритмы сортировки падают, если сравнения не являются самосогласованными. Я вижу, что это работает в любом случае, в зависимости от реализации (decorate-sort-undecorate нужно будет применять «ключ» только один раз для каждого элемента, поэтому будет четко определен). – torek

6

В соответствии с docs:

Перемешайте последовательность х на месте. Необязательный аргумент random - это 0-аргумент, возвращающий случайное поплавок в [0.0, 1.0]; по умолчанию , это функция random().

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

shuffle изменяет список на месте. Это хорошо, потому что копирование большого списка будет чистым накладным, если вам больше не нужен исходный список.

Согласно «явно лучше, чем неявное» принцип pythonic style, возвращая список будет плохая идея, потому что тогда можно было бы подумать, что это новый один, хотя на самом деле это не так.

Если вы сделать нужен свежий список, вы должны написать что-то вроде

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

, который хорошо явно. Если вам нужна эта идиома часто, оберните ее в функцию shuffled (см. sorted), которая возвращает new_x.

23

Думаю, этот метод работает тоже.

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

у меня был момент с ага этой концепции, как это:

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

Поскольку python выполняет «копирование по значениям» по умолчанию вместо pass-by-reference =) http://stackoverflow.com/a/986495/610569 – alvas

1
shuffle(x) 

не возвращает никаких значений. Вместо этого эта функция перетасовывает переменную.

Так что не пытайтесь

print shuffle(x) 

вместо этого просто напечатать переменную, как это.

>>> x = ['foo','bar','black','sheep'] 
>>> from random import shuffle 
>>> x 
['bar', 'black', 'foo', 'sheep'] 
Смежные вопросы