オブジェクトのリストがあり、それらをシャッフルしたい。私はrandom.shuffle
メソッドを使用できると思いましたが、リストがオブジェクトの場合は失敗するようです。オブジェクトをシャッフルする方法、またはこれを回避する別の方法はありますか?
import random
class A:
foo = "bar"
a1 = a()
a2 = a()
b = [a1, a2]
print(random.shuffle(b))
これは失敗します。
オブジェクトのリストがあり、それらをシャッフルしたい。私はrandom.shuffle
メソッドを使用できると思いましたが、リストがオブジェクトの場合は失敗するようです。オブジェクトをシャッフルする方法、またはこれを回避する別の方法はありますか?
import random
class A:
foo = "bar"
a1 = a()
a2 = a()
b = [a1, a2]
print(random.shuffle(b))
これは失敗します。
回答:
random.shuffle
うまくいくはずです。オブジェクトがリストである例を次に示します。
from random import shuffle
x = [[i] for i in range(10)]
shuffle(x)
# print(x) gives [[9], [2], [7], [0], [4], [5], [3], [1], [8], [6]]
# of course your results will vary
シャッフルは所定の位置で機能し、Noneを返すことに注意してください。
random
モジュールのドキュメントで詳細に説明されています。
random.sample(x, len(x))
か、単にコピーを作成することができますshuffle
。以下のためにlist.sort
これと同様の問題があり、今があるのですlist.sorted
が、ために同様の変種はありませんshuffle
。
from random import SystemRandom
。代わりに使用してください。cryptorand = SystemRandom()
行3を次の行に追加して変更しますcryptorand.shuffle(x)
あなたがインプレースシャッフルを学んだように問題がありました。私も頻繁に問題を抱えており、リストのコピー方法も忘れがちです。を使用sample(a, len(a))
しlen(a)
て、サンプルサイズとして使用するソリューションです。Pythonのドキュメントについては、https://docs.python.org/3.6/library/random.html#random.sampleを参照してください。
以下random.sample()
は、シャッフルされた結果を新しいリストとして返すシンプルなバージョンです。
import random
a = range(5)
b = random.sample(a, len(a))
print a, b, "two list same:", a == b
# print: [0, 1, 2, 3, 4] [2, 1, 3, 4, 0] two list same: False
# The function sample allows no duplicates.
# Result can be smaller but not larger than the input.
a = range(555)
b = random.sample(a, len(a))
print "no duplicates:", a == list(set(b))
try:
random.sample(a, len(a) + 1)
except ValueError as e:
print "Nope!", e
# print: no duplicates: True
# print: Nope! sample larger than population
old = [1,2,3,4,5]; new = list(old); random.shuffle(new); print(old); print(new)
(replace; newlines)のリストをコピーするだけ
old[:]
リストの浅いコピーもできますold
。
sample()
データ分析のプロトタイピングに特に役立ちます。sample(data, 2)
パイプラインのグルーコードを設定し、それを段階的に「最大化」しlen(data)
ます。
すでにnumpyを使用している場合(科学および金融アプリケーションで非常に人気があります)、インポートを保存できます。
import numpy as np
np.random.shuffle(b)
print(b)
http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.shuffle.html
>>> import random
>>> a = ['hi','world','cat','dog']
>>> random.shuffle(a,random.random)
>>> a
['hi', 'cat', 'dog', 'world']
それは私にとってはうまくいきます。必ずランダム方式を設定してください。
複数のリストがある場合は、順列(リストをシャッフルする方法/リスト内の項目を再配置する方法)を最初に定義してから、すべてのリストに適用することができます。
import random
perm = list(range(len(list_one)))
random.shuffle(perm)
list_one = [list_one[index] for index in perm]
list_two = [list_two[index] for index in perm]
リストが数の多い配列の場合は、より簡単です。
import numpy as np
perm = np.random.permutation(len(list_one))
list_one = list_one[perm]
list_two = list_two[perm]
次mpu
のconsistent_shuffle
機能を持つ小さなユーティリティパッケージを作成しました。
import mpu
# Necessary if you want consistent results
import random
random.seed(8)
# Define example lists
list_one = [1,2,3]
list_two = ['a', 'b', 'c']
# Call the function
list_one, list_two = mpu.consistent_shuffle(list_one, list_two)
mpu.consistent_shuffle
は任意の数の引数を取ります。したがって、3つ以上のリストをシャッフルすることもできます。
from random import random
my_list = range(10)
shuffled_list = sorted(my_list, key=lambda x: random())
この代替手段は、順序付け関数を入れ替えたい一部のアプリケーションに役立つ場合があります。
sorted
、これは機能的な変更であることに注意してください(そのようなことに夢中になっている場合)。
numpy配列を使用random.shuffle
する場合、配列内に作成された重複データを使用する場合があります。
代わりにを使用することnumpy.random.shuffle
です。すでにnumpyで作業している場合、これはジェネリックよりも推奨される方法random.shuffle
です。
例
>>> import numpy as np
>>> import random
使用random.shuffle
:
>>> foo = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> foo
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> random.shuffle(foo)
>>> foo
array([[1, 2, 3],
[1, 2, 3],
[4, 5, 6]])
使用numpy.random.shuffle
:
>>> foo = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> foo
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> np.random.shuffle(foo)
>>> foo
array([[1, 2, 3],
[7, 8, 9],
[4, 5, 6]])
numpy.random.permutation
興味深いかもしれません:stackoverflow.com/questions/15474159/shuffle-vs-permute-numpy
random.shuffle
ドキュメントは叫ぶべきですnumpy配列では使用しないでください
'print func(foo)'は、 'foo'で呼び出された場合の 'func'の戻り値を出力します。ただし、 'shuffle'は戻り値の型としてNoneを持ちます。リストが適切に変更されるため、何も出力されません。回避策:
# shuffle the list in place
random.shuffle(b)
# print it
print(b)
関数型プログラミングスタイルに詳しい場合は、次のラッパー関数を作成することをお勧めします。
def myshuffle(ls):
random.shuffle(ls)
return ls
random.sample(ls, len(ls))
本当にそのルートを下りたいと思うようなものを望みます。
リストをパラメーターとして取り、シャッフルされたバージョンのリストを返す関数を作成できます。
from random import *
def listshuffler(inputlist):
for i in range(len(inputlist)):
swap = randint(0,len(inputlist)-1)
temp = inputlist[swap]
inputlist[swap] = inputlist[i]
inputlist[i] = temp
return inputlist
""" to shuffle random, set random= True """
def shuffle(x,random=False):
shuffled = []
ma = x
if random == True:
rando = [ma[i] for i in np.random.randint(0,len(ma),len(ma))]
return rando
if random == False:
for i in range(len(ma)):
ave = len(ma)//3
if i < ave:
shuffled.append(ma[i+ave])
else:
shuffled.append(ma[i-ave])
return shuffled
ソースファイルにrandom.pyという名前を付けていないこと、および作業ディレクトリにrandom.pycというファイルがないことを確認してください。プログラムがpythons randomモジュールの代わりにローカルのrandom.pyファイルをインポートしようとする可能性があります。 。
def shuffle(_list):
if not _list == []:
import random
list2 = []
while _list != []:
card = random.choice(_list)
_list.remove(card)
list2.append(card)
while list2 != []:
card1 = list2[0]
list2.remove(card1)
_list.append(card1)
return _list
_list.extend(list2)
は、より簡潔で効率的なに置き換えることができます。
計画:重い作業を行うためにライブラリに依存せずにシャッフルを書き出します。例:要素0で始まるリストを最初から調べます。そのための新しいランダムな位置を見つけます。たとえば、6に0の値を6に入れ、6の値を0に入れます。要素1に移動し、このプロセスを繰り返して、残りのリストを繰り返します。
import random
iteration = random.randint(2, 100)
temp_var = 0
while iteration > 0:
for i in range(1, len(my_list)): # have to use range with len()
for j in range(1, len(my_list) - i):
# Using temp_var as my place holder so I don't lose values
temp_var = my_list[i]
my_list[i] = my_list[j]
my_list[j] = temp_var
iteration -= 1
my_list[i], my_list[j] = my_list[j], my_list[i]
正常に動作します。私はここで関数をリストオブジェクトとして試してみました:
from random import shuffle
def foo1():
print "foo1",
def foo2():
print "foo2",
def foo3():
print "foo3",
A=[foo1,foo2,foo3]
for x in A:
x()
print "\r"
shuffle(A)
for y in A:
y()
次のように出力します:foo1 foo2 foo3 foo2 foo3 foo1(最後の行のfooの順序はランダムです)