파이썬 중복 없이 난수 추출 / 리스트에서 값 뽑기 방법 정리파이썬에서 중복을 허가하지 않고 특정 범위 내의 숫자(정수)들 중 원하는 개수의 숫자들을 뽑거나 리스트 내에서 특정 개수의 자료들을 샘플링하는 방법을 정리해보겠습니다. 중복되지 않게 숫자들을 뽑기이 과정은 넘파이의 random.choice 함수를 사용하시면 편리한데, np.random.choice(range(시작 숫자, 끝 숫자+1), 개수, replace = False) 형태의 코드로 원하는 시작 숫자 ~ 끝 숫자 범위 내에서 특정 개수만큼 중복 없이 난수 샘플링이 가능합니다. 가령, 로또 번호의 예시로 1~45의 숫자들 중 6개를 뽑는 방법은 다음과 같습니다.
위에서 함수 실행 결과(numbers)는 numpy array 자료형이므로, 리스트 변환을 원하시면 numbers = list(numbers) 형태의 코드로 변환을 해주시면 됩니다. 중복되지 않게 리스트 내에서 값들을 랜덤 추출하기이 경우도 위처럼 넘파이의 random.choice 함수를 적용하여 편리하게 추출이 가능합니다. np.random.choice(리스트, 개수, replace = False) 형태의 코드로 리스트 내에서 특정 개수의 자료를 중복 없이 가져올 수 있습니다. 또한, p 인자를 통하여 추출될 확률들의 리스트도 지정 가능하니 참고하세요. (미지정 시 균일 확률이며, p 리스트 숫자 합계는 1이어야 하고, 난수 추출에도 적용 가능합니다.)
마찬가지로, 반환된 결과의 자료형은 넘파이 배열 타입이라는 점을 참고해주세요. 이번에는 리스트에 map 함수를 사용해보겠습니다. map은 리스트의 요소를 지정된 함수로 처리해주는 함수입니다(튜플에도 map 함수를 사용할 수 있으며 원본 튜플을 변경하는 것이 아니라 새 튜플을 생성합니다).
예를 들어 실수가 저장된 리스트가 있을 때 이 리스트의 모든 요소를 정수로 변환하려면 어떻게 해야 할까요? 먼저 for 반복문을 사용해서 변환해보겠습니다. >>> a = [1.2, 2.5, 3.7, 4.6] >>> for i in range(len(a)): ... a[i] = int(a[i]) ... >>> a [1, 2, 3, 4] for에 range(len(a))를 사용해서 인덱스를 가져왔습니다. 그리고 가져온 인덱스로 요소 하나하나에 접근한 뒤 int로 변환하여 다시 저장했습니다. 매번 for 반복문으로 반복하면서 요소를 변환하려니 조금 번거롭습니다. 이때는 map 함수를 사용하면 편리합니다. >>> a = [1.2, 2.5, 3.7, 4.6] >>> a = list(map(int, a)) >>> a [1, 2, 3, 4] a = list(map(int, a)) 한 줄로 변환이 끝났습니다. map에 int와 리스트를 넣으면 리스트의 모든 요소를 int를 사용해서 변환합니다. 그리고 list를 사용해서 map의 결과를 다시 리스트로 만들어줍니다. ▼ 그림 20-5 리스트에 map 함수 사용사실 map에는 리스트뿐만 아니라 모든 반복 가능한 객체를 넣을 수 있습니다. 여기서는 range를 사용해서 숫자를 만든 뒤에 숫자를 문자열로 변환해보겠습니다. >>> a = list(map(str, range(10))) >>> a ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] range로 0부터 9까지 숫자를 만들고, str을 이용해서 모두 문자열로 변환했습니다. 리스트를 출력해보면 각 요소가 ' '(작은따옴표)로 묶인 것을 볼 수 있습니다. 지금까지 input().split()으로 값을 여러 개 입력받고 정수, 실수로 변환할 때도 map을 사용했었죠? 사실 input().split()의 결과가 문자열 리스트라서 map을 사용할 수 있었습니다. 다음과 같이 input().split()을 사용한 뒤에 변수 한 개에 저장해보면 리스트인지 확인할 수 있습니다. >>> a = input().split() 10 20 (입력) >>> a ['10', '20'] 10 20을 입력하면 ['10', '20']처럼 문자열 두 개가 들어있는 리스트가 만들어집니다. 이제 map을 사용해서 정수로 변환해봅시다. >>> a = map(int, input().split()) 10 20 (입력) >>> a <map object at 0x03DFB0D0> >>> list(a) [10, 20] 다시 10 20을 입력하면 맵 객체(map object)가 만들어집니다. 이 상태로는 안에 들어있는 값을 볼 수 없으므로 list를 사용해서 리스트로 출력했습니다. 리스트를 보면 [10, 20]처럼 정수 두 개가 들어있습니다. 이 리스트를 변수 두 개에 저장하면 지금까지 사용한 a, b = map(int, input().split())와 같은 동작이 됩니다. >>> a, b = [10, 20] >>> a 10 >>> b 20 사실 map 함수가 반환하는 맵 객체는 이터레이터라서 변수 여러 개에 저장하는 언패킹(unpacking)이 가능합니다. 그래서 a, b = map(int, input().split())처럼 list를 생략한 것입니다. a, b = map(int, input().split())을 풀어서 쓰면 다음과 같은 코드가 됩니다. x = input().split() # input().split()의 결과는 문자열 리스트 x = map(int, x) # 리스트의 요소를 int로 변환, 결과는 맵 객체 a, b = x # 맵 객체는 변수 여러 개에 저장할 수 있음 내용이 조금 어렵죠? 이처럼 파이썬은 여러 가지 함수를 조합해서 결과를 만들어냅니다. 초보때는 이해하기가 쉽지 않은 부분이니 이런 것도 있구나 하고 넘어가도 됩니다. |