web-dev-qa-db-ja.com

オブジェクトのリストをシャッフルする

私はPythonのオブジェクトのリストを持っていて、それらをシャッフルしたいのです。私はrandom.shuffleメソッドを使うことができると思いました、しかしリストがオブジェクトのものであるとき、これは失敗するようです。オブジェクトをシャッフルする方法はありますか。

import random

class a:
    foo = "bar"

a1 = a()
a2 = a()
b = [a1,a2]

print random.shuffle(b)

これは失敗します。

655
utdiscant

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を返します。

1089
tom10

あなたが学んだように、インプレースシャッフリングが問題でした。私も頻繁に問題を抱えていて、リストをコピーする方法も忘れているようです。 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
100
Ted

それにも時間がかかりました。しかし、shuffleのドキュメントは非常に明確です。

シャッフルリストx 所定の位置に ; Noneを返します。

だからあなたはprint random.shuffle(b)すべきではありません。代わりにrandom.shuffle(b)を実行してからprint bを実行してください。

43
Ohad Cohen
#!/usr/bin/python3

import random

s=list(range(5))
random.shuffle(s) # << shuffle before print or assignment
print(s)

# print: [2, 4, 1, 3, 0]
33
Michael

たまたまナンプーを使用しているのであれば(科学および金融用途で非常に人気があります)、あなたは自分自身で輸入を節約することができます。

import numpy as np    
np.random.shuffle(b)
print(b)

http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.shuffle.html

26
fantabolous
>>> import random
>>> a = ['hi','world','cat','dog']
>>> random.shuffle(a,random.random)
>>> a
['hi', 'cat', 'dog', 'world']

それは私にとってはうまくいきます。必ずランダム方式を設定してください。

22
Dan Lorenc

複数のリストがある場合は、最初に順列(リストのシャッフル/リスト内のアイテムの並べ替え方法)を定義してから、それをすべてのリストに適用します。

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 関数を持つ小さなユーティリティパッケージ mpu を作成しました。

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つ以上のリストをシャッフルすることもできます。

11
Martin Thoma
from random import random
my_list = range(10)
shuffled_list = sorted(my_list, key=lambda x: random())

この代替手段は、順序付け関数を入れ替えたいアプリケーションには便利かもしれません。

7
Jeff

Numpy配列を使用しているときにrandom.shuffleを使用すると、配列内に重複データが作成されることがありました。

別の方法は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]])
5
Gordon Bean

'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
5
JonDoe
import random

class a:
    foo = "bar"

a1 = a()
a2 = a()
a3 = a()
a4 = a()
b = [a1,a2,a3,a4]

random.shuffle(b)
print(b)

shuffleは適切に配置されているので、Noneという結果を表示しないで、リストを表示してください。

2
ravi tanwar

shuffledと呼ばれる関数を定義することができます(sortsortedの同じ意味で)

def shuffled(x):
    import random
    y = x[:]
    random.shuffle(y)
    return y

x = shuffled([1, 2, 3, 4])
print x
2
malbarbo

ワンライナーの場合は、例を挙げてrandom.sample(list_to_be_shuffled, length_of_the_list)を使用します。

import random
random.sample(list(range(10)), 10)

出力:[2、9、7、8、3、0、4、1、6、5]

2
weiyixie

パラメータとしてリストを受け取り、シャッフルされたバージョンのリストを返す関数を作成することができます。

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
0
user8327014
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
0
Pogramist

あなたはこれのために行くことができます:

>>> A = ['r','a','n','d','o','m']
>>> B = [1,2,3,4,5,6]
>>> import random
>>> random.sample(A+B, len(A+B))
[3, 'r', 4, 'n', 6, 5, 'm', 2, 1, 'a', 'o', 'd']

2つのリストに戻りたい場合は、この長いリストを2つに分割します。

0
kiriloff

ソースファイルにrandom.pyという名前を付けていないこと、そして作業ディレクトリにrandom.pycという名前のファイルがないことを確認してください。どちらもpythons randomモジュールの代わりにローカルのrandom.pyファイルをインポートしようとする可能性があります。 。

0
user3298224
""" 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
0
Josh Anish
import random
class a:
    foo = "bar"

a1 = a()
a2 = a()
b = [a1.foo,a2.foo]
random.shuffle(b)
0
Xavier

シャッフルまたはサンプルのどちらでも使用できます。どちらもランダムモジュールから来ています。

import random
def shuffle(arr1):
    n=len(arr1)
    b=random.sample(arr1,n)
    return b

OR

import random
def shuffle(arr1):
    random.shuffle(arr1)
    return arr1
0
ravi tanwar