Python'da neden random.shuffle
geri dönüyor None
?
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
Yerine karıştırılmış değeri nasıl elde ederim None
?
Python'da neden random.shuffle
geri dönüyor None
?
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
Yerine karıştırılmış değeri nasıl elde ederim None
?
Yanıtlar:
random.shuffle()
değiştiren x
listeyi yerinde .
Yerinde bir yapıyı değiştiren Python API yöntemleri, değiştirilmiş None
veri yapısını değil, genellikle döndürür .
Mevcut listenin düzenli tutulduğu mevcut bir listeye dayalı olarak rastgele karıştırılmış yeni bir liste oluşturmak isterseniz random.sample()
, girdinin tam uzunluğu ile kullanabilirsiniz :
x = ['foo', 'bar', 'black', 'sheep']
random.sample(x, len(x))
Ayrıca kullanabilirsiniz sorted()
ile random.random()
bir sıralama anahtarı için:
shuffled = sorted(x, key=lambda k: random.random())
ancak bu, sıralamayı (bir O (NlogN) işlemi) çağırırken, giriş uzunluğuna örnekleme yalnızca O (N) işlemlerini alır ( random.shuffle()
kullanılan işlemin aynısı , daralan bir havuzdan rasgele değerleri değiştirerek).
Demo:
>>> 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
işlev kullanmak gerçekten garanti ediliyor mu? Karşılaştırmalar kendiliğinden tutarlı değilse bazı hızlı sıralama algoritmaları başarısız olur. Bunun uygulamaya bağlı olarak her iki şekilde de çalıştığını görebiliyorum (dekore et-sırala-undecorate key
her öğeye yalnızca bir kez uygulanması gerektiğinden iyi tanımlanmış olacaktır).
key
çağrılabilir ile sıralarken dekorasyon-sırala-süslemesini kullanır . Yani evet, her bir değere rastgele anahtarları tam olarak bir kez verildiği için garantilidir.
Dokümanlara göre :
X dizisini yerinde karıştırın. İsteğe bağlı rastgele argüman, [0.0, 1.0) 'da rastgele bir kayan nokta döndüren bir 0 bağımsız değişken işlevidir; varsayılan olarak bu, random () işlevidir.
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> shuffle(x)
>>> x
['bar', 'black', 'sheep', 'foo']
shuffle
listeyi yerinde değiştirir. Bu güzel, çünkü artık orijinal listeye ihtiyacınız yoksa, büyük bir listenin kopyalanması tamamen ek yük olacaktır.
Göre "açık örtük daha iyidir" prensibi pythonic tarzı sonra kimse düşünebilir çünkü listesini dönen, kötü bir fikir olacağını, olduğunu aslında olmamasına rağmen bir yenisi.
Eğer varsa do taze listesi gerekir, gibi bir şey yazmak zorunda kalacak
new_x = list(x) # make a copy
random.shuffle(new_x)
ki bu çok açık. Bu deyime sık sık ihtiyaç duyuyorsanız, onu geri dönen bir fonksiyona shuffled
(bakınız sorted
) sarın new_x
.
Bu konseptle şöyle bir anım oldu:
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']
Yapıyı yerinde değiştiren Python API'leri , çıktı olarak None döndürür .
list = [1,2,3,4,5,6,7,8]
print(list)
Çıktı: [1, 2, 3, 4, 5, 6, 7, 8]
from random import shuffle
print(shuffle(list))
Çıktı: Yok
from random import sample
print(sample(list, len(list)))
Çıktı: [7, 3, 2, 4, 5, 6, 1, 8]
Karıştırılmış listeyi random.sample()
başkaları tarafından açıklandığı gibi kullanarak geri verebilirsiniz . Listeden k elemanı değiştirmeden örnekleyerek çalışır . Dolayısıyla, listenizde yinelenen öğeler varsa, benzersiz şekilde ele alınacaktır.
>>> 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]