Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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())

но это вызывает сортировку (операция 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']

Ответ 2

Этот метод тоже работает.

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

Ответ 3

Согласно docs:

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

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

Ответ 4

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

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

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

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

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

Ответ 5

У меня был мой аха-момент с этой концепцией:

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

Ответ 6

shuffle(x)

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

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

print shuffle(x)

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

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

Ответ 7

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

list = [1,2,3,4,5,6,7,8]
print(list)

Выход: [1, 2, 3, 4, 5, 6, 7, 8]

from random import shuffle
print(shuffle(list))

Выход: нет

from random import sample
print(sample(list, len(list)))

Выход: [7, 3, 2, 4, 5, 6, 1, 8]

Ответ 8

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

Как уже указывалось, random.shuffle заменяется на месте, поэтому вам не понадобится новая переменная списка.

Ответ 9

Вы можете вернуть перемешанный список с помощью random.sample() как объяснено другими. Он работает путем выборки k элементов из списка без замены. Поэтому, если в вашем списке есть дубликаты, они будут обрабатываться уникально.

>>> l = [1,4,5,3,5]
>>> random.sample(l,len(l))
[4, 5, 5, 3, 1]
>>> random.sample(l,len(l)-1)
[4, 1, 5, 3]
>>> random.sample(l,len(l)-1)
[3, 5, 5, 1]