How do I create a list of random numbers without duplicates?

前端 未结 17 2256
灰色年华
灰色年华 2020-11-22 13:30

I tried using random.randint(0, 100), but some numbers were the same. Is there a method/module to create a list unique random numbers?

Note: The fol

相关标签:
17条回答
  • 2020-11-22 13:50

    A very simple function that also solves your problem

    from random import randint
    
    data = []
    
    def unique_rand(inicial, limit, total):
    
            data = []
    
            i = 0
    
            while i < total:
                number = randint(inicial, limit)
                if number not in data:
                    data.append(number)
                    i += 1
    
            return data
    
    
    data = unique_rand(1, 60, 6)
    
    print(data)
    
    
    """
    
    prints something like 
    
    [34, 45, 2, 36, 25, 32]
    
    """
    
    0 讨论(0)
  • 2020-11-22 13:50
    import random
    result=[]
    for i in range(1,50):
        rng=random.randint(1,20)
        result.append(rng)
    
    0 讨论(0)
  • 2020-11-22 13:54

    In order to obtain a program that generates a list of random values without duplicates that is deterministic, efficient and built with basic programming constructs consider the function extractSamples defined below,

    def extractSamples(populationSize, sampleSize, intervalLst) :
        import random
        if (sampleSize > populationSize) :
            raise ValueError("sampleSize = "+str(sampleSize) +" > populationSize (= " + str(populationSize) + ")")
        samples = []
        while (len(samples) < sampleSize) :
            i = random.randint(0, (len(intervalLst)-1))
            (a,b) = intervalLst[i]
            sample = random.randint(a,b)
            if (a==b) :
                intervalLst.pop(i)
            elif (a == sample) : # shorten beginning of interval                                                                                                                                           
                intervalLst[i] = (sample+1, b)
            elif ( sample == b) : # shorten interval end                                                                                                                                                   
                intervalLst[i] = (a, sample - 1)
            else :
                intervalLst[i] = (a, sample - 1)
                intervalLst.append((sample+1, b))
            samples.append(sample)
        return samples
    

    The basic idea is to keep track of intervals intervalLst for possible values from which to select our required elements from. This is deterministic in the sense that we are guaranteed to generate a sample within a fixed number of steps (solely dependent on populationSize and sampleSize).

    To use the above function to generate our required list,

    In [3]: populationSize, sampleSize = 10**17, 10**5
    
    In [4]: %time lst1 = extractSamples(populationSize, sampleSize, [(0, populationSize-1)])
    CPU times: user 289 ms, sys: 9.96 ms, total: 299 ms
    Wall time: 293 ms
    
    

    We may also compare with an earlier solution (for a lower value of populationSize)

    In [5]: populationSize, sampleSize = 10**8, 10**5
    
    In [6]: %time lst = random.sample(range(populationSize), sampleSize)
    CPU times: user 1.89 s, sys: 299 ms, total: 2.19 s
    Wall time: 2.18 s
    
    In [7]: %time lst1 = extractSamples(populationSize, sampleSize, [(0, populationSize-1)])
    CPU times: user 449 ms, sys: 8.92 ms, total: 458 ms
    Wall time: 442 ms
    

    Note that I reduced populationSize value as it produces Memory Error for higher values when using the random.sample solution (also mentioned in previous answers here and here). For above values, we can also observe that extractSamples outperforms the random.sample approach.

    P.S. : Though the core approach is similar to my earlier answer, there are substantial modifications in implementation as well as approach alongwith improvement in clarity.

    0 讨论(0)
  • 2020-11-22 13:55

    The solution presented in this answer works, but it could become problematic with memory if the sample size is small, but the population is huge (e.g. random.sample(insanelyLargeNumber, 10)).

    To fix that, I would go with this:

    answer = set()
    sampleSize = 10
    answerSize = 0
    
    while answerSize < sampleSize:
        r = random.randint(0,100)
        if r not in answer:
            answerSize += 1
            answer.add(r)
    
    # answer now contains 10 unique, random integers from 0.. 100
    
    0 讨论(0)
  • 2020-11-22 13:57

    From the CLI in win xp:

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

    In Canada we have the 6/49 Lotto. I just wrap the above code in lotto.bat and run C:\home\lotto.bat or just C:\home\lotto.

    Because random.randint often repeats a number, I use set with range(7) and then shorten it to a length of 6.

    Occasionally if a number repeats more than 2 times the resulting list length will be less than 6.

    EDIT: However, random.sample(range(6,49),6) is the correct way to go.

    0 讨论(0)
提交回复
热议问题