まず、リンク先のページに書いてあるrand_ints_nodup
の性能そのものがよくないですね。
「a
以上b
以下の疑似乱数を生成し、それまでの疑似乱数のリストに存在しなければ合計c
個になるまでリストに追加する」というアルゴリズムなので、a
とb
の差が大きく、c
の値がb - a
に近いと、リストに値を追加するのに時間がかかるようになります。残りの値の候補が少ないのに、毎回a
以上b
以下の乱数を生成するからですね。
試しに、rand_ints_nodup(1, 10000, 10000)
で実行時間を計測したら、私のPCでは5~10秒ほどかかっていました。後で示す別のコードだと、0.02秒前後で同様の結果が得られます。
重複しない乱数のリストを得るアルゴリズムは、「乱数のシャッフル」で検索すると見つかります。「フィッシャー–イェーツのシャッフル - Wikipedia」に、バリエーションも含めていろいろ載っています。
もっとも、Pythonで結果を得るには、randomモジュール自体にシャッフル用のメソッドが含まれているので、自分でアルゴリズムを実装する必要はありません。random.shuffle
やrandom.sample
がそうです。
元になるリストとは別に、シャッフルされたリストを生成するrandom.sample
を使うと、先ほどのrand_ints_nodup
は以下のように書けます(わざわざ関数にするほどではないのですが、比較用に)。
Python
1def rand_ints_nodup(a, b, c):
2 return random.sample(range(a, b + 1), c)
次に、「座席表のような物に表示する」方法ですが、単に縦・横に整理して表示するだけでよければ、
Python
1lst = rand_ints_nodup(1, 40, 40)
2
3n = 8
4for i, v in enumerate(lst):
5 print(f"{v:2d}", end='\n' if i % n == n - 1 else ' ')
6
7print()
のようにすれば、空白区切りで横n
列に並べることができます。カンマ区切りに変更してCSVファイルとして保存することもできます。
result
121 33 6 26 31 10 3 27
2 9 25 36 7 17 19 4 38
329 8 5 18 12 39 24 30
432 1 16 14 40 11 37 2
535 13 20 34 15 28 23 22
6