Si vous avez besoin d'échantillonner des nombres extrêmement importants, vous ne pouvez pas utiliser range
random.sample(range(10000000000000000000000000000000), 10)
parce qu'il jette :
OverflowError: Python int too large to convert to C ssize_t
En outre, si random.sample
ne peut pas produire le nombre d'articles que vous souhaitez parce que la gamme est trop petite
random.sample(range(2), 1000)
il jette :
ValueError: Sample larger than population
Cette fonction résout les deux problèmes :
import random
def random_sample(count, start, stop, step=1):
def gen_random():
while True:
yield random.randrange(start, stop, step)
def gen_n_unique(source, n):
seen = set()
seenadd = seen.add
for i in (i for i in source() if i not in seen and not seenadd(i)):
yield i
if len(seen) == n:
break
return [i for i in gen_n_unique(gen_random,
min(count, int(abs(stop - start) / abs(step))))]
Utilisation avec des nombres extrêmement grands :
print('\n'.join(map(str, random_sample(10, 2, 10000000000000000000000000000000))))
Résultat de l'échantillon :
7822019936001013053229712669368
6289033704329783896566642145909
2473484300603494430244265004275
5842266362922067540967510912174
6775107889200427514968714189847
9674137095837778645652621150351
9969632214348349234653730196586
1397846105816635294077965449171
3911263633583030536971422042360
9864578596169364050929858013943
Utilisation lorsque la plage est inférieure au nombre d'éléments demandés :
print(', '.join(map(str, random_sample(100000, 0, 3))))
Résultat de l'échantillon :
2, 0, 1
Il fonctionne également avec des plages et des étapes négatives :
print(', '.join(map(str, random_sample(10, 10, -10, -2))))
print(', '.join(map(str, random_sample(10, 5, -5, -2))))
Résultats de l'échantillon :
2, -8, 6, -2, -4, 0, 4, 10, -6, 8
-3, 1, 5, -1, 3
2 votes
S'ils sont uniques, ils peuvent être véritablement aléatoires dans le bon contexte. Comme un échantillon aléatoire d'index sans remplacement peut encore être complètement aléatoire.