본문 바로가기

Random 모듈

'random' 모듈은 의사 난수(pseudo-random)를 생성합니다. 'randint(a,b)'로 정수, 'random()'으로 0~1 실수를 생성하고, 'choice()'로 요소 선택, 'shuffle()'로 순서 섞기가 가능합니다.

1. Random 모듈

1.1 Random 라이브러리

파이썬의 random 라이브러리는 다양한 유형의 무작위 수 생성 기능을 제공합니다. 하지만 엄밀히 말해 진짜 난수는 아닙니다.

이 모듈은 메르센 트위스터라는 난수 생성기를 사용합니다. 다양한 언어에서 채택하고 있는 방식으로, 시드(seed)라는 초기값에서 출발해 정해진 계산으로 다음 수를 만들어냅니다. 그래서 시드를 같게 맞추면 언제 실행해도 똑같은 순서의 수가 나옵니다. 규칙이 있는 것이죠. 이렇게 만들어진 수를 의사 난수(pseudo-random)라고 합니다.

import random

random.seed(42)
print([random.randint(1, 100) for _ in range(5)])

random.seed(42)  # 같은 시드로 되돌리면
print([random.randint(1, 100) for _ in range(5)])  # 같은 결과가 나옵니다.

이 성질은 실험이나 테스트를 재현할 때 유용합니다. 같은 시드를 쓰면 어제 돌린 결과를 오늘 그대로 재현할 수 있기 때문입니다.

이렇게 생성된 수는 게임, 시뮬레이션, 테스트 데이터 생성, 표본 추출 등 다양한 분야에서 활용되며, 다음과 같은 메서드를 제공합니다.

보안이 필요한 곳에는 random을 쓰지 마세요.

random은 시드와 이전 값을 알면 다음 값을 예측할 수 있습니다. 비밀번호 초기화 토큰, 인증 코드, 세션 키처럼 남이 알아맞히면 안 되는 값을 이 모듈로 만들면 심각한 보안 취약점이 됩니다.

이런 용도에는 예측이 불가능하도록 설계된 secrets 모듈을 사용해야 합니다.

import secrets

print(secrets.token_hex(16))       # 임의의 16바이트 토큰
print(secrets.randbelow(1000000))  # 0 이상 1000000 미만의 정수
print(secrets.choice(['a', 'b', 'c']))

1.1.1 난수 생성(Random Number Generation)

  • randint(a, b): a와 b 사이의 무작위 정수를 생성합니다. b도 범위에 포함됩니다.
  • randrange(start, stop[, step]): 지정된 범위에서 무작위 정수를 반환합니다. start부터 stop - 1까지, 선택적으로 step을 지정할 수 있습니다.
  • random(): 0과 1 사이의 무작위 실수를 반환합니다.

1.1.2 시퀀스 내 요소 무작위 선택 및 조작

  • choice(sequence): 주어진 시퀀스(리스트, 튜플 등)에서 임의의 요소를 선택합니다.
  • shuffle(sequence): 주어진 시퀀스의 요소 순서를 무작위로 섞습니다.
  • sample(sequence, k): 주어진 시퀀스에서 k개의 무작위 요소를 선택합니다.

1.1.3 분포 기반 난수 생성

  • uniform(a, b): 주어진 범위 내에서 균등 분포를 따르는 무작위 실수를 반환합니다.
  • normalvariate(mu, sigma): 정규 분포를 따르는 무작위 실수를 반환합니다. 여기서 mu는 평균, sigma는 표준편차입니다.

1.2 Random 라이브러리 사용 예시

여기서는 자주 사용되는 메서드를 살펴보도록 하겠습니다.

1.2.1 난수 생성

import random

# randint: a와 b 사이의 무작위 정수 생성
random_int = random.randint(1, 10)
print("Random integer:", random_int)

# random: 0과 1 사이의 무작위 실수 생성
random_float = random.random()
print("Random float:", random_float)

1.2.2 시퀀스 내 요소 무작위 선택 및 조작

# choice: 시퀀스에서 임의의 요소 선택
colors = ['red', 'blue', 'green', 'yellow']
chosen_color = random.choice(colors)
print("Chosen color:", chosen_color)

# shuffle: 시퀀스의 요소 순서 섞기
random.shuffle(colors)
print("Shuffled colors:", colors)

shuffle은 원본을 그 자리에서 섞어버리고 아무것도 반환하지 않습니다. 원본을 남겨두고 싶다면 sample을 사용하세요.

import random

colors = ['red', 'blue', 'green', 'yellow']

# sample: 원본을 건드리지 않고 k개를 뽑습니다.
print(random.sample(colors, 2))
print(random.sample(colors, len(colors)))  # 전체를 섞은 새 리스트
print(colors)  # 원본은 그대로입니다.

choice는 중복을 허용하고, sample은 중복 없이 뽑습니다. 중복을 허용하면서 여러 개를 뽑고 싶다면 choices를 사용합니다.

import random

colors = ['red', 'blue', 'green', 'yellow']

print(random.choices(colors, k=5))  # 중복 허용, 5개
print(random.sample(colors, 3))     # 중복 없이 3개

1.2.3 분포 기반 난수 생성

import random

print(random.uniform(1, 10))              # 1과 10 사이의 실수, 균등 분포
print(random.normalvariate(170, 10))      # 평균 170, 표준편차 10인 정규 분포