Pythonのリストをシャッフルする(ランダムに並び替える):shuffleとsampleを使う
2023.02.18
Python のリストは random の shuffle でシャッフルします。
import random
a = ['apple', 'grape', 'lemon']
random.shuffle(a)
print(a)
# ['lemon', 'grape', 'apple']
shuffle はもとのリストを変えます。つまりもとのリストがシャッフル後のリストになります。返り値はだいたい None です。
import random
a = ['apple', 'grape', 'lemon']
b = random.shuffle(a)
print(a) # ['lemon', 'grape', 'apple']
print(b) # None
Python のシャッフルは sample のほうが扱いやすい、かもしれない
random の sample もリストをシャッフルしますが、こちらはシャッフルしたリストを返します。
import random
a = ['apple', 'grape', 'lemon']
b = random.sample(a, len(a))
print(a) # ['apple', 'grape', 'lemon']
print(b) # ['lemon', 'apple', 'grape']
もとのリストは変わっていません。ここが shuffle と大きく違うところです。
- shuffle はもとのリストを変える
- sample はもとのリストを変えず、シャッフルしたリストを返す
しかし sample はシャッフルに使う要素数をあらかじめ指定しないといけません。上のコードでは第二引数に len(a)
を入れています。下の例は要素数を変えたときのシャッフル・リストの変化を示しています。
import random
x = [1, 2, 3, 4, 5]
a = random.sample(x, 1)
b = random.sample(x, 2)
c = random.sample(x, 3)
d = random.sample(x, 4)
e = random.sample(x, 5)
print(x) # [1, 2, 3, 4, 5]
print(a) # [4]
print(b) # [5, 1]
print(c) # [3, 1, 5]
print(d) # [4, 1, 3, 2]
print(e) # [1, 4, 5, 3, 2]
要素数を指定できる分だけ sample は shuffle よりも使いやすいでしょう。ここで要素数を 0 にしたらどうでしょうか?
import random
x = [1, 2, 3, 4, 5]
a = random.sample(x, 0)
print(x) # [1, 2, 3, 4, 5]
print(a) # []
例外はなく、きちんと空のリストが返りました。要素数がもとのリストの長さを超えたらどうでしょう?
import random
x = [1, 2, 3, 4, 5]
a = random.sample(x, 6)
print(x) # [1, 2, 3, 4, 5]
print(a)
# ValueError: Sample larger than population or is negative
ValueError となりました。長さを超える要素数は指定できないとわかります。リストを単純にシャッフルしたいときは len(a)
を指定するといいでしょう。
乱数を使う
乱数を使ったシャッフルも可能です。乱数は random の seed に任意の整数を入れて生成します。
import random
random.seed(10)
x = [1, 2, 3, 4, 5]
random.shuffle(x)
print(x) # [4, 3, 2, 1, 5]
何回もシャッフルしてみましょう。
import random
random.seed(10)
x = [1, 2, 3, 4, 5]
for i in range(10):
random.shuffle(x)
print(x)
結果:
[4, 3, 2, 1, 5]
[2, 3, 1, 4, 5]
[3, 2, 5, 1, 4]
[5, 4, 2, 1, 3]
[1, 3, 5, 2, 4]
[1, 2, 4, 5, 3]
[5, 1, 2, 3, 4]
[3, 1, 5, 4, 2]
[3, 2, 5, 4, 1]
[2, 5, 4, 1, 3]
シャッフルのたびに異なるリストが出力されました。