Чому random.shuffle
повернення None
в Python?
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
Як отримати замішане значення замість None
?
Чому random.shuffle
повернення None
в Python?
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
Як отримати замішане значення замість None
?
Відповіді:
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']
key
справді гарантоване використання випадкової функції? Деякі алгоритми швидкого сортування падають, якщо порівняння не узгоджуються самостійно. Я бачу, що це працює в будь-якому випадку, залежно від реалізації (decorate-sort-undecorate потрібно буде застосувати лише key
один раз до кожного елементу, тому буде чітко визначено).
key
виклику. Так що так, це гарантовано, оскільки кожному значенню дається випадковий ключ рівно один раз.
Відповідно до документів :
Перемішайте послідовність x на місці. Необов’язковий аргумент random - це 0-аргументна функція, що повертає випадковий плаваючий запуск у [0.0, 1.0); за замовчуванням це функція random ().
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> shuffle(x)
>>> x
['bar', 'black', 'sheep', 'foo']
shuffle
змінює список на місці. Це приємно, тому що копіювання великого списку було б просто накладним, якщо оригінальний список вам більше не потрібен.
Відповідно до принципу "явне краще, ніж неявне" пітонічного стилю , повернення списку було б поганою ідеєю, оскільки тоді можна подумати, що це новий, хоча насправді це не так.
Якщо вам дійсно потрібен свіжий список, ви повинні написати що - щось на зразок
new_x = list(x) # make a copy
random.shuffle(new_x)
що є приємним явним. Якщо вам часто потрібна ця ідіома, оберніть її у функцію 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']
API Python, які змінюють структуру на місці, повертає 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]
Ви можете повернути перемішаний список, використовуючи 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]