12

Pythonに特定の数値以外の乱数を生成させるにはどうすればよいですか? たとえば、3 を除く 1 から 5 までの任意の数値を生成するようにしたいので、出力はリストに含まれず、カウントさ1, 2, 4, 53ません。それを達成するために何ができますか?

例は次のようになります:ゲームに
はコンピュータ化された5人のプレイヤー (プレイヤー 0 から 4) がいます。
プレイヤー 1 はランダムに1 人のプレイヤー (自分自身を除く) を選択し、プレイヤー 2 から 4 も同じことを行います。

したがって、出力は次のようになります。

Player 1, who do you want to play with?
Player 1 chooses Player 2
4

6 に答える 6

18

リストで使用random.choiceしますが、最初にその特定の番号をリストから削除します。

>>> import random
>>> n = 3
>>> end  = 5
>>> r = range(1,n) + range(n+1, end)
>>> r
[1, 2, 4]
>>> random.choice(r)
2
>>> random.choice(r)
4

または関数を定義します。

def func(n, end, start = 1):
    return range(start, n) + range(n+1, end)
... 
>>> r = func(3, 5)
>>> r
[1, 2, 4]
>>> random.choice(r)
2

アップデート:

これは、リストから特定の番号以外のすべての番号を返します。

>>> r = range(5)
for player in r:
    others = range(0, player) + range(player+1, 5)
    print player,'-->', others
...     
0 --> [1, 2, 3, 4]
1 --> [0, 2, 3, 4]
2 --> [0, 1, 3, 4]
3 --> [0, 1, 2, 4]
4 --> [0, 1, 2, 3]
于 2013-07-28T10:24:01.103 に答える
5

乱数のセットを生成し、それらから 1 つずつ選択するかのように聞こえます。つまり、繰り返しのないランダムなシーケンスです。

これらすべての数字を生成し、シャッフル.pop()してから、一度に 1 つずつ選択し、一連の可能性からそれを削除します。

import random

numbers = range(5)  # list(range(5)) in Python 3
random.shuffle(numbers)

a_random_number = numbers.pop()
another_random_number = numbers.pop()

list.pop()ランダムにシャッフルされた数値のリストから最後の値を削除します。

リストをシャッフルしてからループするだけでも十分な場合があります。

players = range(5)
random.shuffle(players)

for player in players:
    # random ordering of players

乱数列の生成を関数の反復子としてまとめることができます。

import random

def random_number_sequence(n):
    numbers = range(n)  # list(range(n)) in Python 3
    random.shuffle(numbers)
    return iter(numbers)

random_sequence = random_number_sequence(5)
a_random_number = next(numbers)
another_random_number = next(numbers)

イテレータを呼び出すと、シーケンスが使い果たされるまで (その時点で が返されます) next()、シーケンスから別の乱数が生成されます。StopIteration

于 2013-07-28T10:49:48.970 に答える
4

他の答えは正しいですが。中間リストの使用は非効率的です。


別の解決策: これを行う別の方法は、サイズが n-1 の範囲の数値からランダムに選択することです。次に、スキップする数値以上の結果に +1 を追加します。

次の関数random_choice_exceptは と同じ API を実装しているnp.random.choiceため、調整するsizeことで複数のランダム値を効率的に生成できます。


import numpy as np

def random_choice_except(a: int, excluding: int, size=None, replace=True):
    # generate random values in the range [0, a)
    choices = np.random.choice(a-1, size, replace=replace)
    # shift values to avoid the excluded number
    return choices + (choices >= excluding)

random_choice_except(3, 1)
# >>> 0  <or>  2  
random_choice_except(3, 1)
# >>> [0 2 0 0 0 2 2 0 0 2]

np.random.choice整数、リスト、または配列が引数として渡されるかどうかによって、の動作が変わります。望ましくない動作を防ぐために、関数の先頭に次のアサーションを追加することをお勧めします。assert isinstance(a, int)

于 2020-09-22T18:00:50.980 に答える
1

この場合、random.choiceうまく機能しますが、使用できる明らかな単純な数学的変換もあります。プレイヤーの番号が 0 から 5 までで、あなたがプレイヤー X の場合:

number = random.choice(0, 4) # first, pick a number: 0, 1, 2, 3, or 4
if number >= X:              # then, if it's me or higher...
    number += 1              # move forward one player

これは、プレイヤー番号に関係なく機能することに注意してください。あなたが 5 位の場合、これは 0 から 4 の間の数字を選択しますが、これはあなたではありません (あなたは 5 位であるため)。あなたが #0 の場合、これは 0 から 4 の間の数字を選択します。これは >= あなた (あなたは #0 であるため) であるため、1 を追加して 1 から 5 の間の数字を指定します。あなたが #3 の場合、これは次の間の数字を選択します。 0 と 4、3 か 4 の場合は、それぞれ 1 か 4 か 5 に上げます。

編集して追加: これにより、「公正な」交替 (誰かが再び行く前に全員が順番を取得する) を行うことができなくなります。それが必要な場合は、リストを生成し、 を使用random.shuffleしてランダムな順序で配置し、リスト.pop()が空になるまで (または同様の方法で) 選択する方法です。次に、リストを補充して再シャッフルして、新しい(ただし異なる)「公正な」順序にすることができます。

(この種のことは、 「そこにたどり着く方法」に進む前に、が欲しいかを理解することが重要であることに注意してください。)

于 2013-07-28T11:24:10.600 に答える