web-dev-qa-db-ja.com

範囲内で 'n'個の固有の乱数を生成します

私はPythonの範囲内で乱数を生成する方法を知っています。

random.randint(numLow, numHigh)

そして、これをループに入れてn個のこれらの数を生成できることを私は知っています

for x in range (0, n):
    listOfNumbers.append(random.randint(numLow, numHigh))

ただし、そのリストの各番号が一意であることを確認する必要があります。大量の条件文以外に、n個の固有の乱数を生成する簡単な方法はありますか?

編集:重要なことは、リスト内の各番号は他のものとは異なることです。

そう

[12、5、6、1] =良い

しかし

[12、5、5、1] =悪い、なぜなら5という数は2回発生するからです。

165
Chris Headleand

交換せずにサンプリングが必要なだけの場合:

>>> import random
>>> random.sample(range(1, 100), 3)
[77, 52, 45]

random.sample は母集団と標本サイズkを取り、母集団のkランダムメンバーを返します。

klen(population)よりも大きい場合を制御する必要がある場合は、ValueErrorをキャッチする準備をする必要があります。

>>> try:
...   random.sample(range(1, 2), 3)
... except ValueError:
...   print('Sample size exceeded population size.')
... 
Sample size exceeded population size
282

最初にデータの範囲を生成してからこのようにシャッフルします

import random
data = range(numLow, numHigh)
random.shuffle(data)
print data

こうすることで、特定の範囲内のすべての数をランダムな順序で取得できます。

しかし、 random.sample を使用すると、必要な要素数を次のような範囲から取得できます。

print random.sample(range(numLow, numHigh), 3)
22
thefourtheye

setに到達するまで n に追加できます。

setOfNumbers = set()
while len(setOfNumbers) < n:
    setOfNumbers.add(random.randint(numLow, numHigh))

nに収まる範囲よりも小さい範囲を持つように注意してください。それは永久にループし、nまで挿入する新しい番号を見つけることができません。

12
mhlester

標準ライブラリrandom.sample関数を使用して、人口からk個の要素を選択できます。

import random
random.sample(range(low, high), n)

かなり広い範囲の数の可能性がある場合は、itertools.isliceを無限乱数発生器と共に使用することができます。

import itertools
import random

def random_gen(low, high):
    while True:
        yield random.randrange(low, high)

gen = random_gen(1, 100)
items = list(itertools.islice(gen, 10))  # take first 10 random elements

_ update _

そのため、質問を更新した後、n個の(一意の)番号が必要であることが明らかになりました。

import itertools
import random

def random_gen(low, high):
    while True:
        yield random.randrange(low, high)

gen = random_gen(1, 100)

items = set()

# try to add elem to set until set length is less than 10
for x in itertools.takewhile(lambda x: len(items) < 10, gen): 
    items.add(x)
4
maxbublis