なぜrandom.shuffle
PythonでNone
を返しますか?
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
None
の代わりにシャッフルされた値を取得するにはどうすればよいですか?
random.shuffle()
はx
リストをインプレースに変更します。
インプレースで構造を変更するPython APIメソッドは、通常、変更されたデータ構造ではなくNone
を返します。
既存のリストに基づいてnewランダムにシャッフルされたリストを作成したい場合、既存のリストは順番に保持されるため、 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']
この方法も機能します。
import random
shuffled = random.sample(original, len(original))
docs によると:
シーケンスxを適切にシャッフルします。オプションの引数randomは、[0.0、1.0)のランダムな浮動小数点数を返す0引数の関数です。デフォルトでは、これは関数random()です。
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> shuffle(x)
>>> x
['bar', 'black', 'sheep', 'foo']
shuffle
は、リストを適切に変更します。元のリストが不要になった場合、大きなリストのコピーは純粋なオーバーヘッドになるため、これは素晴らしいことです。
「暗黙的よりも明示的である」Pythonスタイル の原則によれば、リストを返すことは悪い考えです。実際にはそうではありませんが、それは新しいisと考えるかもしれません。
あなたがdo新しいリストが必要な場合、次のようなものを書く必要があります
new_x = list(x) # make a copy
random.shuffle(new_x)
これは明確に明示されています。このイディオムが頻繁に必要な場合は、new_x
を返す関数shuffled
(sorted
を参照)でラップします。
>> x = ['foo','bar','black','sheep']
>> random.shuffle(x)
>> print(x)
>> ['sheep', 'bar', 'foo', 'black']
指摘したように、random.shuffleはその場で置換されるため、新しいリスト変数は必要ありません。
shuffle(x)
値を返しません。代わりに、その関数は変数自体をシャッフルします。
だから試さないで
print shuffle(x)
代わりに、このように変数を出力するだけです。
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> x
['bar', 'black', 'foo', 'sheep']
私はこのような概念で私の瞬間を過ごしました:
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']
その場で構造自体を変更するPython APIは、出力としてNoneを返します。
list = [1,2,3,4,5,6,7,8]
print(list)
出力:[1、2、3、4、5、6、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]