중복이없는 난수 목록은 어떻게 만듭니 까?


110

나는 사용해 보았다 random.randint(0, 100) 보았지만 일부 숫자는 동일했습니다. 고유 한 난수 목록을 만드는 방법 / 모듈이 있습니까?

참고 : 다음 코드는 답변을 기반으로하며 답변이 게시 된 후 추가되었습니다. 그것은 질문의 일부가 아닙니다. 그것이 해결책입니다.

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);

1
고유 한 경우 올바른 컨텍스트에서 진정으로 무작위 일 수 있습니다. 대체하지 않고 임의의 인덱스 샘플처럼 여전히 완전히 임의적 일 수 있습니다.
gbtimmon

답변:


180

중복없이 0에서 99까지의 범위에서 선택된 10 개의 숫자 목록을 반환합니다.

import random
random.sample(range(100), 10)

특정 코드 예제를 참조하면 파일에서 모든 줄을 한 번 읽은 다음 메모리에 저장된 목록에서 임의의 줄을 선택 하고 싶을 것입니다 . 예를 들면 :

all_lines = f1.readlines()
for i in range(50):
    lines = random.sample(all_lines, 40)

이렇게하면 루프 전에 실제로 파일에서 한 번만 읽어야합니다. 파일의 시작 부분으로 돌아가서 f1.readlines()각 루프 반복을 다시 호출하는 것보다 이렇게하는 것이 훨씬 더 효율적 입니다.


2
이 기술은 특히 큰 샘플의 경우 메모리를 낭비합니다. 아래에 Linear Congruential Generator를 사용하는 훨씬 더 많은 메모리와 계산 효율적인 솔루션에 대한 코드를 게시했습니다.
Thomas Lux

하지만 LCG 방법이 "무작위"가 적다는 점이 지적되었으므로 고유 한 임의 시퀀스를 많이 생성하려면이 솔루션보다 다양성이 적습니다. 소수의 무작위 시퀀스 만 필요하다면 LCG가 최선의 선택입니다!
Thomas Lux

감사합니다 Greg, 유용했습니다
N Sivaram

15

다음 과 같이 임의 모듈 에서 셔플 기능을 사용할 수 있습니다 .

import random

my_list = list(xrange(1,100)) # list of integers from 1 to 99
                              # adjust this boundaries to fit your needs
random.shuffle(my_list)
print my_list # <- List of unique random numbers

여기서 shuffle 메서드는 예상대로 목록을 반환하지 않으며 참조로 전달 된 목록 만 섞습니다.


xrange는 Python 2에서만 작동하고 Python 3에서는 작동하지 않는다는 점을 언급하는 것이 좋습니다.
Shayan Shafiq

10

당신은 처음부터 번호 목록을 만들 수 있습니다 ab어디에, a그리고 b각각 목록에서 가장 작은 및 큰 숫자, 다음과 셔플 피셔 - 예이츠 알고리즘 또는 파이썬의 사용 random.shuffle방법을.


1
인덱스의 전체 목록을 생성하는 것은 특히 큰 샘플의 경우 메모리 낭비입니다. 나는 Linear Congruential Generator를 사용하는 훨씬 더 많은 메모리와 컴퓨팅 효율적인 솔루션에 대한 코드를 게시했습니다.
Thomas Lux

8

이 답변에 제시된 솔루션은 작동하지만 표본 크기는 작지만 모집단이 큰 경우 메모리 문제가 될 수 있습니다 (예 :random.sample(insanelyLargeNumber, 10) 있습니다.

이를 해결하기 위해 다음과 같이하겠습니다.

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

이제 random.sample대규모 모집단의 적은 수의 샘플에이 접근 방식을 사용하므로 메모리 문제는 더 이상 존재하지 않습니다. 이 답변이 작성 random.shuffle되었을 때 구현 이 다를 수 있습니다.
kyrill

5

선형 합동 의사 난수 생성기

O (1) 메모리

O (k) 작업

이 문제는 간단한 선형 합동 생성기 로 해결할 수 있습니다. . 이를 위해서는 일정한 메모리 오버 헤드 (8 개의 정수)와 최대 2 * (시퀀스 길이) 계산이 필요합니다.

다른 모든 솔루션은 더 많은 메모리와 더 많은 컴퓨팅을 사용합니다! 무작위 시퀀스가 ​​몇 개만 필요한 경우이 방법이 훨씬 저렴합니다. size 범위의 N경우 N고유 k시퀀스 이상의 순서로 생성하려는 경우 속도를 위해 파이썬 에서 최적화되었으므로 기본 제공 방법 random.sample(range(N),k)을 사용하여 허용되는 솔루션을 권장합니다 .

암호

# Return a randomized "range" using a Linear Congruential Generator
# to produce the number sequence. Parameters are the same as for 
# python builtin "range".
#   Memory  -- storage for 8 integers, regardless of parameters.
#   Compute -- at most 2*"maximum" steps required to generate sequence.
#
def random_range(start, stop=None, step=None):
    import random, math
    # Set a default values the same way "range" does.
    if (stop == None): start, stop = 0, start
    if (step == None): step = 1
    # Use a mapping to convert a standard range into the desired range.
    mapping = lambda i: (i*step) + start
    # Compute the number of numbers in this range.
    maximum = (stop - start) // step
    # Seed range with a random integer.
    value = random.randint(0,maximum)
    # 
    # Construct an offset, multiplier, and modulus for a linear
    # congruential generator. These generators are cyclic and
    # non-repeating when they maintain the properties:
    # 
    #   1) "modulus" and "offset" are relatively prime.
    #   2) ["multiplier" - 1] is divisible by all prime factors of "modulus".
    #   3) ["multiplier" - 1] is divisible by 4 if "modulus" is divisible by 4.
    # 
    offset = random.randint(0,maximum) * 2 + 1      # Pick a random odd-valued offset.
    multiplier = 4*(maximum//4) + 1                 # Pick a multiplier 1 greater than a multiple of 4.
    modulus = int(2**math.ceil(math.log2(maximum))) # Pick a modulus just big enough to generate all numbers (power of 2).
    # Track how many random numbers have been returned.
    found = 0
    while found < maximum:
        # If this is a valid value, yield it in generator fashion.
        if value < maximum:
            found += 1
            yield mapping(value)
        # Calculate the next value in the sequence.
        value = (value*multiplier + offset) % modulus

용법

이 함수 "random_range"의 사용법은 모든 생성기 ( "range"와 같은)와 동일합니다. 예 :

# Show off random range.
print()
for v in range(3,6):
    v = 2**v
    l = list(random_range(v))
    print("Need",v,"found",len(set(l)),"(min,max)",(min(l),max(l)))
    print("",l)
    print()

샘플 결과

Required 8 cycles to generate a sequence of 8 values.
Need 8 found 8 (min,max) (0, 7)
 [1, 0, 7, 6, 5, 4, 3, 2]

Required 16 cycles to generate a sequence of 9 values.
Need 9 found 9 (min,max) (0, 8)
 [3, 5, 8, 7, 2, 6, 0, 1, 4]

Required 16 cycles to generate a sequence of 16 values.
Need 16 found 16 (min,max) (0, 15)
 [5, 14, 11, 8, 3, 2, 13, 1, 0, 6, 9, 4, 7, 12, 10, 15]

Required 32 cycles to generate a sequence of 17 values.
Need 17 found 17 (min,max) (0, 16)
 [12, 6, 16, 15, 10, 3, 14, 5, 11, 13, 0, 1, 4, 8, 7, 2, ...]

Required 32 cycles to generate a sequence of 32 values.
Need 32 found 32 (min,max) (0, 31)
 [19, 15, 1, 6, 10, 7, 0, 28, 23, 24, 31, 17, 22, 20, 9, ...]

Required 64 cycles to generate a sequence of 33 values.
Need 33 found 33 (min,max) (0, 32)
 [11, 13, 0, 8, 2, 9, 27, 6, 29, 16, 15, 10, 3, 14, 5, 24, ...]

1
이것은 매우 멋지다! 그러나 나는 그것이 정말로 질문에 대한 답이라고 확신합니다. 0에서 4까지 2 개의 값을 샘플링하고 싶다고 가정 해 보겠습니다. 내 자신을 생성하지 않고이 prime함수는 4 개의 가능한 답변 만 반환합니다. 왜냐하면 value적어도 4 개의 가능한 값이 필요할 때 무작위로 선택한 것이기 때문 입니다. (4 choose 2) = 6, (무작위 주문 허용). random_range(2,4){(1, 0), (3, 2), (2, 1), (0, 3)} 값을 반환하지만 쌍 (3,1) (또는 (1,3))은 반환하지 않습니다. 각 함수 호출마다 무작위로 생성 된 새로운 큰 소수를 기대하고 있습니까?
wowserx

1
(또한 사용자가 무작위 순서를 원하는 경우 함수가 시퀀스를 반환 한 후 순서를 섞을 것으로 예상하고 있습니다. 대신 고유 한 시퀀스로 random_range(v)반환 되기 때문 v입니다. v!)
wowserx

완전히 사실입니다! 정수 오버플로를 피하는 것과 충분한 임의의 시퀀스를 생성하는 것 사이의 균형을 맞추기가 어렵습니다. 좀 더 무작위성을 포함하도록 함수를 업데이트했지만 여전히 v!만큼 무작위가 아닙니다. 기능을 여러 번 사용하려는 경우에 따라 다릅니다. 이 솔루션은 큰 범위의 값에서 생성 할 때 가장 적합합니다 (다른 값의 메모리 사용량이 훨씬 더 높을 때). 더 생각 할게요, 고마워요!
Thomas Lux

4

1에서 N까지의 N 개의 숫자 목록이 무작위로 생성되면 예, 일부 숫자가 반복 될 가능성이 있습니다.

임의의 순서로 1에서 N까지의 숫자 목록을 원하면 1에서 N까지의 정수로 배열을 채운 다음 Fisher-Yates 셔플 또는 Python의 random.shuffle().


3

매우 큰 수를 샘플링해야하는 경우 사용할 수 없습니다. range

random.sample(range(10000000000000000000000000000000), 10)

던지기 때문에 :

OverflowError: Python int too large to convert to C ssize_t

또한 random.sample범위가 너무 작아서 원하는 수의 아이템을 생산할 수없는 경우

 random.sample(range(2), 1000)

던졌습니다 :

 ValueError: Sample larger than population

이 기능은 두 가지 문제를 모두 해결합니다.

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))))]

매우 많은 수의 사용 :

print('\n'.join(map(str, random_sample(10, 2, 10000000000000000000000000000000))))

샘플 결과 :

7822019936001013053229712669368
6289033704329783896566642145909
2473484300603494430244265004275
5842266362922067540967510912174
6775107889200427514968714189847
9674137095837778645652621150351
9969632214348349234653730196586
1397846105816635294077965449171
3911263633583030536971422042360
9864578596169364050929858013943

범위가 요청 된 항목 수보다 작은 사용 :

print(', '.join(map(str, random_sample(100000, 0, 3))))

샘플 결과 :

2, 0, 1

음수 범위 및 단계에서도 작동합니다.

print(', '.join(map(str, random_sample(10, 10, -10, -2))))
print(', '.join(map(str, random_sample(10, 5, -5, -2))))

샘플 결과 :

2, -8, 6, -2, -4, 0, 4, 10, -6, 8
-3, 1, 5, -1, 3

당신은 무엇을 통해 80 억 번호, 조만간 볼이 너무 큰 될 것 생성하는 경우
david_adler

이 답변은 큰 샘플에 심각한 결함이 있습니다. 충돌 확률은 각 단계마다 선형 적으로 증가합니다. 나는 O (1) 메모리 오버 헤드와 k 숫자를 생성하는 데 필요한 O (k) 단계가있는 Linear Congruential Generator를 사용하는 솔루션을 게시했습니다. 이것은 훨씬 더 효율적으로 해결할 수 있습니다!
Thomas Lux

이 대답은 시퀀스 길이 순서대로 여러 개의 임의 시퀀스를 생성하려는 경우 확실히 더 좋습니다! LCG 방법은 여러 개의 고유 한 시퀀스를 생성 할 때 덜 "무작위"합니다.
Thomas Lux

"이 기능은 두 문제를 모두 해결합니다." 두 번째 문제는 어떻게 해결합니까? 여전히 2 개의 모집단에서 1000 개의 샘플을 채취 할 수 없습니다. 예외를 던지는 대신 잘못된 결과를 생성합니다. 이것은 "문제"의 해결책이 아닙니다 ( n <k 의 모집단에서 k 개의 고유 한 샘플 을 요청하는 것이 전혀 합리적이지 않기 때문에 처음에는 문제가되지 않습니다 ).
kyrill

1

Numpy 를 사용할 수 있습니다.다음과 같이 빠른 답변을 위해 라이브러리를

주어진 코드 스 니펫 은 0에서 5 사이의 6 개의 고유 한 숫자를 나열합니다 . 사용자의 편의를 위해 매개 변수를 조정할 수 있습니다.

import numpy as np
import random
a = np.linspace( 0, 5, 6 )
random.shuffle(a)
print(a)

산출

[ 2.  1.  5.  3.  4.  0.]

여기에 언급 된 random.sample에서 볼 수있는 제약 조건을 두지 않습니다 .

이것이 도움이되기를 바랍니다.


1

여기에 제공된 대답은 시간과 메모리 측면에서 매우 잘 작동하지만 yield와 같은 고급 파이썬 구조를 사용하기 때문에 조금 더 복잡합니다. 더 간단한 대답 은 실제로 잘 작동하지만 그 대답의 문제는 실제로 필요한 집합을 구성하기 전에 많은 가짜 정수를 생성 할 수 있다는 것입니다. populationSize = 1000, sampleSize = 999로 시도해보십시오. 이론적으로 종료되지 않을 가능성이 있습니다.

아래 답변은 현재 다른 두 가지만큼 효율적이지 않지만 결정적이며 다소 효율적이기 때문에 두 가지 문제를 모두 해결합니다.

def randomSample(populationSize, sampleSize):
  populationStr = str(populationSize)
  dTree, samples = {}, []
  for i in range(sampleSize):
    val, dTree = getElem(populationStr, dTree, '')
    samples.append(int(val))
  return samples, dTree

getElem, percolateUp 함수는 아래에 정의 된 것과 같습니다.

import random

def getElem(populationStr, dTree, key):
  msd  = int(populationStr[0])
  if not key in dTree.keys():
    dTree[key] = range(msd + 1)
  idx = random.randint(0, len(dTree[key]) - 1)
  key = key +  str(dTree[key][idx])
  if len(populationStr) == 1:
    dTree[key[:-1]].pop(idx)
    return key, (percolateUp(dTree, key[:-1]))
  newPopulation = populationStr[1:]
  if int(key[-1]) != msd:
    newPopulation = str(10**(len(newPopulation)) - 1)
  return getElem(newPopulation, dTree, key)

def percolateUp(dTree, key):
  while (dTree[key] == []):
    dTree[key[:-1]].remove( int(key[-1]) )
    key = key[:-1]
  return dTree

마지막으로 아래와 같이 n 값이 큰 경우 평균 타이밍은 약 15ms였습니다.

In [3]: n = 10000000000000000000000000000000

In [4]: %time l,t = randomSample(n, 5)
Wall time: 15 ms

In [5]: l
Out[5]:
[10000000000000000000000000000000L,
 5731058186417515132221063394952L,
 85813091721736310254927217189L,
 6349042316505875821781301073204L,
 2356846126709988590164624736328L]

대답이 복잡 하다고 생각 하세요? 이게 뭐야?! 그리고 많은 "가짜 정수"를 생성 하는 또 다른 대답이 있습니다. 사용자가 제공 한 예제 입력으로 구현을 실행했습니다 (populationSize = 1000, sampleSize = 999). 귀하의 버전은 random.randint함수를 3996 번 호출하는 반면 다른 하나는 cca를 호출합니다 . 6000 배. 크게 개선되지 않았나요?
kyrill


1

결정적이고 효율적이며 기본 프로그래밍 구조로 빌드 된 중복없이 임의 값 목록을 생성하는 프로그램을 얻으려면 extractSamples아래 정의 된 함수를 고려하십시오 .

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

기본 아이디어는 intervalLst필요한 요소를 선택할 수있는 가능한 값 의 간격 을 추적하는 것입니다 . 이는 고정 된 수의 단계 내에서 샘플을 생성 할 수 있다는 점에서 결정적입니다 ( populationSizesampleSize 임).

위 함수를 사용하여 필수 목록을 생성하려면

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

또한 이전 솔루션과 비교할 수도 있습니다 (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

솔루션을 populationSize사용할 때 더 높은 값에 대해 메모리 오류를 생성 하므로 값을 줄였습니다 random.sample( 여기여기 이전 답변에서도 언급 됨 ). 위의 값에 extractSamples대해 random.sample접근 방식 을 능가하는 것도 관찰 할 수 있습니다 .

추신 : 핵심 접근 방식은 이전 답변 과 유사하지만 명확성 향상과 함께 구현 및 접근 방식에 상당한 수정이 있습니다.


0

문제를 해결하는 매우 간단한 기능

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

집합 기반 접근 방식 ( "반환 값의 임의 값인 경우 다시 시도")의 문제점은 특히 많은 양의 임의 값이 반환되는 경우 충돌 (또 다른 "다시 시도"반복이 필요함)으로 인해 런타임이 결정되지 않는다는 것입니다. 범위에서.

이 비 결정적 런타임에 취약하지 않은 대안은 다음과 같습니다.

import bisect
import random

def fast_sample(low, high, num):
    """ Samples :param num: integer numbers in range of
        [:param low:, :param high:) without replacement
        by maintaining a list of ranges of values that
        are permitted.

        This list of ranges is used to map a random number
        of a contiguous a range (`r_n`) to a permissible
        number `r` (from `ranges`).
    """
    ranges = [high]
    high_ = high - 1
    while len(ranges) - 1 < num:
        # generate a random number from an ever decreasing
        # contiguous range (which we'll map to the true
        # random number).
        # consider an example with low=0, high=10,
        # part way through this loop with:
        #
        # ranges = [0, 2, 3, 7, 9, 10]
        #
        # r_n :-> r
        #   0 :-> 1
        #   1 :-> 4
        #   2 :-> 5
        #   3 :-> 6
        #   4 :-> 8
        r_n = random.randint(low, high_)
        range_index = bisect.bisect_left(ranges, r_n)
        r = r_n + range_index
        for i in xrange(range_index, len(ranges)):
            if ranges[i] <= r:
                # as many "gaps" we iterate over, as much
                # is the true random value (`r`) shifted.
                r = r_n + i + 1
            elif ranges[i] > r_n:
                break
        # mark `r` as another "gap" of the original
        # [low, high) range.
        ranges.insert(i, r)
        # Fewer values possible.
        high_ -= 1
    # `ranges` happens to contain the result.
    return ranges[:-1]

0
import random

sourcelist=[]
resultlist=[]

for x in range(100):
    sourcelist.append(x)

for y in sourcelist:
    resultlist.insert(random.randint(0,len(resultlist)),y)

print (resultlist)

1
Stackoverflow에 오신 것을 환영합니다. 다른 사람들이 귀하의 답변을 쉽게 이해할 수 있도록 귀하의 답변이 문제를 해결하는 이유와 방법을 설명하십시오.
옥토 버스

이 코드가 문제를 해결할 수 있지만 문제를 해결하는 방법과 이유에 대한 설명포함 하여 게시물의 품질을 향상시키는 데 실제로 도움이되며 더 많은 찬성 투표가 발생할 수 있습니다. 지금 질문하는 사람뿐만 아니라 미래에 독자를 위해 질문에 답하고 있다는 것을 기억하십시오. 제발 편집 설명을 추가하고 제한 및 가정이 적용 무엇의 표시를 제공하는 답변을. 리뷰에서
double-beep

-1

추가되는 번호가 고유한지 확인하려면 Set 객체를 사용할 수 있습니다.

2.7 이상을 사용하는 경우, 그렇지 않은 경우 sets 모듈을 가져옵니다.

다른 사람들이 언급했듯이 이것은 숫자가 실제로 무작위가 아님을 의미합니다.


-1

minval와 사이의 교체없이 정수를 샘플링합니다 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]

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]

많은 요소의 순열을 생성 한 다음 n_samples그중 첫 번째 요소 만 선택하는 이유는 무엇 입니까? 이 접근 방식의 이유는 무엇입니까? 기존의 많은 답변 (대부분 8 년 전 답변)과 비교하여 접근 방식의 장점이 무엇인지 설명해 주시겠습니까?
kyrill

실제로 내 대답은 다른 최고 투표 답변과 유사하며 numpy를 사용하기 때문에 더 빠릅니다. 다른 최고 투표 방법 random.shuffle은 Mersenne Twister를 사용하는를 사용하며, qhich는 numpy (그리고 아마도 jax)가 제공하는 algos보다 훨씬 느립니다. numpy 및 jax는 다른 난수 생성 알고리즘을 허용합니다. jax는 또한 jit 컴파일 및 미분을 허용하므로 확률 적 미분에 유용 할 수 있습니다. 또한, "가능성이 큰"배열에 관한 일부 상단 답변과 똑같이 할 투표 random.shuffle내가 상대 또는 절대 의미에서 죄라고 생각하지 않는다
grisaitis을

1
" random.shuffle메르 센 트위스터를 사용합니다 " 가 무슨 뜻인지 잘 모르겠습니다 . 여러 답변에서 언급했듯이 Fisher-Yates 셔플입니다. 선형 시간 복잡성이 있으므로 다른 라이브러리, numpy 또는 기타에서 제공하는 알고리즘보다 점근 적으로 느릴 수 없습니다. numpy가 더 빠르면 C에 내장되어 있기 때문일뿐입니다. 그러나 이것은 엄청난 순열 (메모리에 맞지 않을 수도있는)을 생성하는 것을 보증하지 않고 몇 가지 요소 만 선택해야합니다. 이것을하는 당신 외에는 단 하나의 대답 이 없습니다 .
키릴

내 사과, 나는 파이썬 랜덤이 Mersenne Twister를 사용했다고 읽었습니다. Fisher Yates와 random.shuffle의 역할에 대해 자세히 알아볼 수있는 출처가 있습니까?
grisaitis

여기에 두 개의 별도 답변에 대한 Wikipedia에 대한 두 개의 별도 링크가 이미 있습니다. Wikipedia가 충분한 출처가 아니라면 기사 끝에 14 개의 참고 문헌이 있습니다. 그리고 구글이 있습니다. 도움이 되나요? 아, 그리고random 모듈은 Python으로 작성되었으므로 소스를 쉽게 볼 수 있습니다 (try random.__file__).
kyrill

-3

win xp의 CLI에서 :

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

캐나다에는 6/49 Lotto가 있습니다. 위의 코드를 lotto.bat에 래핑하고 실행 C:\home\lotto.bat하거나C:\home\lotto .

random.randint숫자를 자주 반복 하기 때문에 setwith range(7)를 사용한 다음 길이를 6으로 줄입니다.

때때로 숫자가 2 배 이상 반복되는 경우 결과 목록 길이가 6 미만이됩니다.

편집 : 그러나 random.sample(range(6,49),6)올바른 방법입니다.


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

1
이것이 중복을 피하는 방법을 설명해 주시겠습니까? 이 코드 덤프에서는 명확하지 않습니다.
Toby Speight 2018

그렇지 않습니다. print len(result), len(set(result)). 시도 result할 때마다 한 번만 고유 한 요소가 있을 것으로 예상 할 수 1.0851831788708547256608362340568947172111832359638926... × 10^20있습니다.
Jedi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.