198 votes

Comment créer une liste de nombres aléatoires sans doublons ?

J'ai essayé d'utiliser random.randint(0, 100) mais certains numéros sont les mêmes. Existe-t-il une méthode/module pour créer une liste de nombres aléatoires uniques ?

Note : Le code suivant est sur la base d'une réponse et a été ajouté après que la réponse ait été postée. Il ne fait pas partie de la question ; il constitue la solution.

def getScores():
    # open files to read and write
    f1 = open("page.txt", "r");
    p1 = open("pgRes.txt", "a");

    gScores = [];
    bScores = [];
    yScores = [];

    # run 50 tests of 40 random queries to implement "bootstrapping" method 
    for i in range(50):
        # get 40 random queries from the 50
        lines = random.sample(f1.readlines(), 40);

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.

-2voto

grisaitis Points 112

Pour échantillonner des entiers sans remplacement entre minval y maxval :

import numpy as np

minval, maxval, n_samples = -50, 50, 10
generator = np.random.default_rng(seed=0)
samples = generator.permutation(np.arange(minval, maxval))[:n_samples]

# or, if minval is 0,
samples = generator.permutation(maxval)[:n_samples]

avec Jax :

import jax

minval, maxval, n_samples = -50, 50, 10
key = jax.random.PRNGKey(seed=0)
samples = jax.random.shuffle(key, jax.numpy.arange(minval, maxval))[:n_samples]

0 votes

Pourquoi générer une permutation d'un grand nombre d'éléments et ne sélectionner que le premier élément ? n_samples d'eux ? Quel est votre raisonnement derrière cette approche ? Pouvez-vous expliquer quels sont les avantages de votre approche, par rapport au grand nombre de réponses existantes (la plupart datant d'il y a 8 ans) ?

0 votes

En fait, ma réponse a une complexité similaire à celle des autres réponses les plus votées et est plus rapide car elle utilise numpy. Les autres méthodes les plus votées utilisent random.shuffle qui utilise Mersenne Twister, qui est beaucoup plus lent que les algorithmes offerts par numpy (et probablement jax). numpy et jax permettent d'utiliser d'autres algorithmes de génération de nombres aléatoires. jax permet également la compilation et la différentiation en jit, ce qui peut être utile pour la différentiation stochastique. également, en ce qui concerne un tableau "éventuellement grand", certaines des réponses les plus votées font exactement la même chose avec random.shuffle Je ne pense pas que ce soit un péché dans un sens relatif ou même absolu.

1 votes

Je ne suis pas sûr de ce que vous voulez dire par " random.shuffle utilise Mersenne Twister", c'est le mélange de Fisher-Yates, comme mentionné dans plusieurs réponses. Il a une complexité temporelle linéaire, il est donc impossible qu'il soit asymptotiquement plus lent que les algorithmes proposés par toute autre bibliothèque, numpy ou autre. Si numpy est plus rapide, c'est uniquement parce qu'il est implémenté en C, mais cela ne justifie pas de générer une énorme permutation (qui pourrait même ne pas tenir en mémoire), seulement pour en choisir quelques éléments. Il n'y a pas de simple réponse à part la vôtre qui fait cela.

-2voto

Illinoisey Points 1

Si le nombre de numéros que vous voulez est aléatoire, vous pouvez faire quelque chose comme ceci. Dans ce cas, la longueur est le nombre le plus élevé parmi lequel vous voulez choisir.

S'il s'aperçoit que le nouveau numéro aléatoire a déjà été choisi, il soustrait 1 du compte (puisqu'un compte a été ajouté avant qu'il ne sache s'il s'agit d'un doublon ou non). Si le numéro n'est pas dans la liste, faites-en ce que vous voulez et ajoutez-le à la liste pour qu'il ne soit pas choisi à nouveau.

import random
def randomizer(): 
            chosen_number=[]
            count=0
            user_input = int(input("Enter number for how many rows to randomly select: "))
            numlist=[]
            #length = whatever the highest number you want to choose from
            while 1<=user_input<=length:
                count=count+1
                if count>user_input:
                    break
                else:
                    chosen_number = random.randint(0, length)
                    if line_number in numlist:
                        count=count-1
                        continue
                    if chosen_number not in numlist:
                        numlist.append(chosen_number)
                        #do what you want here

-3voto

exbctel Points 87

A partir de la CLI dans win xp :

python -c "import random; print(sorted(set([random.randint(6,49) for i in range(7)]))[:6])"

Au Canada, nous avons le loto 6/49. Je mets le code ci-dessus dans le fichier lotto.bat et je l'exécute. C:\home\lotto.bat ou simplement C:\home\lotto .

Parce que random.randint répète souvent un numéro, j'utilise set con range(7) et ensuite le raccourcir à une longueur de 6.

Parfois, si un nombre se répète plus de 2 fois, la longueur de la liste résultante sera inférieure à 6.

EDIT : Cependant, random.sample(range(6,49),6) est la voie à suivre.

-3voto

user2904400 Points 1
import random
result=[]
for i in range(1,50):
    rng=random.randint(1,20)
    result.append(rng)

1 votes

Pourriez-vous expliquer comment cela permet d'éviter les doublons ? Ce n'est pas évident à partir de ce vidage de code.

0 votes

Ce n'est pas le cas. print len(result), len(set(result)) . On s'attendrait à voir que result n'aurait des éléments uniques qu'une fois par 1.0851831788708547256608362340568947172111832359638926... × 10^20 essaie.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X