Чому 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]