|
1: 2019-03-31 (日) 17:09:32 njf |
| + | *元のリストを変更してランダムに並べ替える [#u62df709] |
| | | |
| + | 元のリストを変更してランダムに並べ替えるには、random.shuffle()を使います。 |
| + | |
| + | import random |
| + | |
| + | randomList = [0,1,2] |
| + | |
| + | random.shuffle(randomList) |
| + | |
| + | print(randomList) |
| + | |
| + | 結果 |
| + | [1, 0, 2] |
| + | など。 |
| + | |
| + | もとのリストが変更されていることに注意して下さい。 |
| + | |
| + | もとのリストを変更せずに新たにランダムなリストを作るには以下のようにします。 |
| + | |
| + | *元のリストを変更せず、ランダムに並び替えられたリストを新たに得る [#m891760c] |
| + | |
| + | random.sample()を使います。このメソッドは好きな数のランダムなサンプルをリストで返す関数です。二つ引数をとり、一つ目が元になるリスト、二つ目が返すリストの長さです。二つ目の引数を元のリストの長さと同じにすれば、もとのリストをランダムに並び替えた新たなリストを返します。 |
| + | |
| + | import random |
| + | |
| + | randomList = [0,1,2] |
| + | |
| + | newRandomList = random.sample(randomList,len(randomList)) |
| + | |
| + | print(newRandomList) |
| + | |
| + | 結果 |
| + | [1, 2, 0] |
| + | など。 |
| + | |
| + | *よくあるサンプルにはだまされないように [#x1b6384d] |
| + | |
| + | 「配列 ランダム 並び替え」などでインターネット検索すると次のようなコードを記載したページが上位に現れます。 |
| + | randomList = [0,1,2] |
| + | |
| + | listLen=len(randomList) |
| + | |
| + | for i in range(listLen): |
| + | a = randomList[i] |
| + | j = random.randrange(0,listLen) |
| + | randomList[i] = randomList[j] |
| + | randomList[j] = a |
| + | |
| + | つまり、配列から順に要素を選び、次にランダムに配列を一つ選び、この二つを入れ替えていく物です。 |
| + | |
| + | これは結果がかなりかたよります。 |
| + | |
| + | 実際、このアルゴリズムで100,000回ランダムな(のはず)入れ替えを行ってみると、 |
| + | |
| + | 0,2,1 18651 |
| + | 0,1,2 14885 |
| + | 2,1,0 14889 |
| + | 1,2,0 18359 |
| + | 2,0,1 14742 |
| + | 1,0,2 18474 |
| + | |
| + | となり、明らかに14800ぐらいのものと、18500ぐらいのものに二分されました。 |
| + | |
| + | これは[[こちら:http://nmi.jp/archives/541]]の記事で指摘されているように、アルゴリズムの構造的な欠陥です。 |
| + | |
| + | たとえば3つのものの並べ替えの結果は3!=6通りですが、上のアルゴリズムでは3回3つの要素をランダムに入れ替えるので、3*3*3=27通りです。 |
| + | |
| + | 27は6で割り切れませんから、かならず上のアルゴリズムはそれぞれの結果に対して、どれかが多く、どれかが少ない並べ替えを行っています。(詳しくは[[上記記事:http://nmi.jp/archives/541]]にあります。) |
| + | |
| + | 今は長さ3の配列ですが、配列の長さが大きくなるにつれて不均等になりやすくなることも分かっています。 |
| + | |
| + | よって、プログラマの意図しない結果がもたらされる可能性があり、なるべく使うべきではありません。 |
| + | |
| + | pythonにはrandom.shuffleがあるのですから、わざわざ手間をかけてバグとなりかねない物を入れるより、素直にこれを使いましょう。 |
| + | |
| + | random.shuffleで同じように100,000回実行してみると結果は、 |
| + | |
| + | 0,2,1 16597 |
| + | 0,1,2 16750 |
| + | 2,1,0 16986 |
| + | 1,2,0 16579 |
| + | 2,0,1 16564 |
| + | 1,0,2 16524 |
| + | |
| + | といったものになり、均等に並び替えられていることが分かります。 |