파이썬 특강 4부

난수 생성

무작위 수를 생성할 필요가 종종 있다. 무작위로 생성된 수를 난수(random number)라 부르며, 난수 생성을 위해 랜덤(random) 모듈을 사용할 수 있다.

random 함수

0과 1 사이의 실수를 무작위로, 하지만 균등하게(uniformly) 선택한다. 여기서 균등성은 한 영역에 치우치지 전 영역에서 골고루 선택함을 의미한다.

주의: 난수 생성이 엄밀히 말하면 완전히 무작위는 아니다. 모든 컴퓨터 안에 난수표가 있어서 random 같은 함수를 실행할 때마다 난수표에서 차례대로 읽어서 보여주는 것에 불과하다. 하지만 우리 인간에게는 무작위적으로 보이며, 실제로 매우 유용하게 활용된다.

시드(seed) 함수

코드를 실행할 때 마다 동일한 난수를 얻으려면, 즉, 동일한 환경에서 데이터 분석 실험을 반복하려면 seed 함수를 먼저 실행해야 한다.

간단한게 설명하면, seed 함수에 입력된 정수 인자가 난수를 생성하는 기준을 제시한다. 따라서 어떤 환경에서도 seed 함수의 입력값이 동일하면 동일한 난수가 생성된다.

시드를 지정하지 않으면 random 함수가 매번 다른 값을 생성한다.

randrange 함수

지정된 범위 안에서 정수를 무작위로 선택하는 함수이다.

예를 들어, 0부터 9 사이의 정수중에서 임의로 하나의 수를 선택하려면 다음과 같이 실행한다.

실행할 때마다 다른 값을 반환한다.

그리고, 예를 들어, 3과 7 사이의 정수 중에서 임의로 하나를 선택하려면 다음과 같이 실행한다.

역시 실행할 때마다 다른 값을 반환한다.

하지만 seed 를 지정하면 매번 동일한 값을 반환한다.

shuffle 함수

리스트의 항목들을 무작위로 섞고자 할 때 사용한다.

역시 실행할 때마다 다르게 섞는다.

하지만 시드를 지정하면 항상 동일한 결과를 보인다.

choice 함수

리스트에서 임의로 하나의 항목을 선택할 때 사용한다.

실행할 때마다 값이 달라질 수 있다. 그리고 중복 선택이 가능하다.

시드를 지정하면 동일한 결과를 얻는다.

sample 함수

리스트에서 지정한 개수만큼의 항목을 무작위로 선택해서 새로운 리스트를 생성할 수도 있다. 중복선택이 없다. 따라서 일종의 로또 뽑기와 비슷하게 작동한다.

실행할 때 마다 다르게 선택한다.

시드를 지정하면 변하지 않는다.

choicerange의 합작

두 함수를 합작하면 sample 함수와 유사하게 작동하는 코드를 구현할 수 있다. 차이점은 중복 선택이 가능하다라는 점이다.

예를 들어, 0부터 99 사이의 정수 중에서 중복을 허락하면서 무작위로 10개의 정수를 선택하고자 할 때 다음과 같이 실행한다.

실행할 때마다 결과가 다르다.

시드를 지정하면 항상 동일하다.

정규표현식

정규표현식은 문장을 탐색할 때 매우 유용하며, 탐색 대상의 패턴(pattern, 형태)을 지정한다. 하지만 사용법이 꽤 복잡하기도 해서 한 권의 책으로 나올 정도이다. 따라서 앞으로 정규표현식 예제가 나올 때마다 필요한 정도만 자세히 다룰 것이며, 여기서는 간단하 예제를 통해 정규표현식의 역할을 살펴본다.

먼저, 정규표현식 탐색에 필요한 도구를 모아놓은 re 모듈을 불러와야 한다.

match 함수

예를 들어, 문자열이 ca로 시작하는지 여부를 알고자 하면 다음처럼 실행한다. 패턴 매칭이 성립하면 Match 객체가 리턴되며 매칭이 성공했음을 알려준다.

위 결과는 cat 문자열의 0번부터 2번 이전 인덱스까지 지정된 패턴으로 시작된다는 정보를 보여준다.

반면에 패턴 매칭이 성공하지 못하면 None을 리턴한다.

패턴 매칭 성공과 실패: True 또는 False

패턴 매칭이 성공하면 True, 실패하면 False로 간주된다.

search 함수

대괄호([]) 패턴 규칙

지금 까지는 특정 문자열의 포함여부만을 살펴보았다. 하지만 특정 문자열 뿐만 아니라 특정 형태를 띄는 문자열을 탐색할 수도 있다.

예를 들어, 0부터 9까지의 숫자 중 하나로 시작 또는 포함하는지 여부를 물을 수 있다. 이를 위해 사용할 패턴은 [0-9] 이다.

split 함수

예를 들어, a 또는 b로 문자열을 쪼개고자 할 때 다음처럼 실행한다.

즉, "caribbean""c"-a-"ri"-b-""-b-"e"-a-"n"로 쪼개졌다.

sub 함수

예를 들어, 0부터 9까지의 숫자 대신에 대시(-)를 사용하고 싶으면 아래와 같이 실행한다.

참고자료

정규표현식에 대한 정보와 활용법은 매우 중요하며 아래 사이트를 이용하여 공부할 것을 추천한다.

짝짓지(zip) 함수와 인자 해체(argument unpacking)

리스트, 튜플 등 이터러블(iterable) 자료형 두 개 이상을 짝짓기를 통해 하나로 묶어야 할 때가 있다. 예를 들어, 두 개의 리스트의 항목을 순서대로 쌍으로 묶어 새로운 리스트를 생성할 수 있다.

zip은 소극적인 함수이다. 즉, 필요한 만큼만 계산하고 결과를 생성한다.

따라서 결과물을 확인하려면 아래와 같이 리스트 조건제시법 등을 활용해야 한다.

서로 길이가 다른 리스트를 대상으로 zip 함수를 사용하면 가장 짧은 리스트의 길이만큼만 짝짓기를 실행한다.

인자 해체(argument unpacking)

숫자 세 개의 평균을 계산해주는 함수를 아래와 같이 정의하자.

이제 mean3 함수를 호출하려면 반드시 인자 두 개를 입력해야 한다.

그런데 길이가 3인 리스트나 튜플을 인자로 사용할 수 있다. 대신 인자를 해체해야 하며 이를 위해 별표(*)를 사용한다.

주의: 별표를 사용하지 않으면 오류가 발생한다.

짝짓기 해체

인자 해체 기술을 응용하여 짝짓기가 된 쌍들의 리스트를 해체하여 두 개의 리스트로 되돌릴 수 있다. 다만 방식이 꽤나 생소하게 보일 수 있다.

앞서 zip으로 생성한 list_pairs를 해체해서 기존 두 개의 리스트를 복구해보자.

list_pairs를 아래 형태의 리스트를 소극적(lazy)으로 담고 있다.

이제 pairs를 해체하면서 zip 함수의 인자로 입력하면 아래 세 개의 인자를 zip 함수의 인자로 입력하는 것과 동일하다.

('a', 0), ('b', 1), ('c', 2)

따라서 zip(*pairs)는 아래 모양의 리스트를 품은 값이 된다.

[('a', 'b', 'c'), (0, 1, 2)]

아래 코드를 실행하면 동일한 결과를 확인할 수 있다.

일반 인자들과 옵션 인자들

함수를 선언할 때 아래 형태처럼 인자의 개수를 지정하는 것이 일반적이다.

def 함수이름(매개변수1, ..., 매개변수n):
    함수본체

하지만 원하는 대로 많은 인자를 받을 수 있도록 해야 하는 경우가 발생한다. 이를 위해 파이썬은 관습적으로 argskwargs라 불리며 특별한 역할을 수행하는 매개변수를 사용한다.

꽤 유용한 기법이지만 여기서는 고계함수를 선언하면서 반드시 필요한 경우에 한정해서 사용할 것이다.

고계함수(higer-order function)

파이썬에서 함수는 제1종 객체이며, 따라서 다른 함수의 인자로 사용될 수 있다. 이렇게 함수를 인자로 입력받을 수 있는 함수를 고계함수(higher-order function)라 부른다.

예를 들어, 함수 f를 입력 받으면 f의 반환값의 두 배를 반환하는 새로운 함수를 반환하는 doubler 함수를 정의해 보자.

doubler 함수의 인자로 다음 함수 f1을 사용해보자.

g(x)f(x)의 두 배임을 확인할 수 있다.

하지만 두 개의 인자를 받는 다음 함수 f2에 대해서는 doubler를 실행시킬 수 없다.

임의로 많은 인자를 입력 받는 함수

임의로 많은 인자를 받는 함수를 선언하는 일반적인 형식은 아래 magic 함수의 경우와 비슷하다.

주의:

주의:

인자 해체 활용

리스트, 튜플, 사전 자료형을 해체 기법으로 함수의 인자로 동시에 입력할 수도 있다.

예를 들어, 아래 함수는 인자 세 개를 요구한다.

이제 길이가 2인 리스트 한 개와 한 개의 항목을 가진 사전 자료형을 해체 기법을 이용하여 인자로 사용해보자.

임의로 많은 인자를 받는 함수와 고계함수

앞서 살펴 본 doubler 함수를 일반화 하여 임의로 많은 인자를 받은 함수를 인자로 사용할 수 있도록 argskwargs 기법을 이용할 수 있다.

이제 f2에 대해서도 2배 함수가 작동한다.

자료형 명시하기

파이썬과 동적 타이핑

파이썬은 동적 타이핑(dynamic typing)을 지원하는 언어이다. 즉, 함수나 변수를 선언할 때 변수들의 자료형을 명시적으로 제한하지 않는다. 동적 타이핑 언어의 경우 프로그램 실행 과정에서 문제가 발생하지 않도록 프로그램을 작성해야 한다.

예를 들어 아래 add 함수를 보자.

add 함수의 인자로 정수, 실수, 리스트, 문자열이 사용될 수 있다.

하지만 두 인자가 동일한 자료형을 가져야 한다. 예를 들어, 숫자와 문자열의 덧셈은 작동하지 않는다. 이유는 숫자와 문자열의 덧셈이 정의되어 있지 않기 때문이다.

파이썬과 정적 타이핑

C, Java 등 많은 프로그래밍 언어는 동적 타이핑 대신에 정적 타이핑(static typing)을 지원한다. 즉, 함수나 변수를 선언할 때 사용되는 변수들의 자료형과 인자 및 반환값의 자료형을 애초부터 명시해야 하며 지정된 자료형이 사용되지 않을 경우 오류를 발생시킨다.

파이썬은 3.6 버전부터 정적 타이핑 형식을 지원한다. 다만 C, Java의 자료형과 관련된 엄격함은 전혀 존재하지 않으며, 그냥 정적 타이핑의 형식만 빌려왔다.

즉, 자료형 명시(type annotations)를 지원할 뿐이며, 실제로는 동적 타이핑 방식을 사용한다. 예를 들어, add 함수를 아래와 같이 선언할 수 있다.

하지만 여전히 문자열이나 리스트를 인자로 사용할 수 있다.

자료형 명시하기의 장점

비록 형식적더라도 자료형 명시하기가 주는 장점이 크게 네 가지이다.

첫째, 문서화 및 프로그래밍 교육에 유용하다.

예를 위해, 먼저 벡터 자료형을 실수들의 리스트들의 집합으로 정의하자.

이제 아래 두 개의 정의를 비교하면 둘째 정의가 보다 많은 정보를 우리에게 제공함을 알 수 있다.

정의 1: 전통적 방식

정의 2: 자료형 명시

둘째, mypy 와 같은 제3자가 개발한 툴을 이용하여 파이썬 코드를 실행하기 전에 작성된 코드에 사용된 함수와 변수들이 적절한 자료형을 사용했는지 여부를 검사해주는 툴을 활용할 수 있다.

하지만 여기서는 사용하지 않을 것이며, 대신에 관심이 있다면 mypy 공식 문서를 참조하기를 추천한다.

셋째, 자료형을 명시적으로 보여줌으로써 보다 정제된 함수와 인터페이스를 디자인할 수 있다.

예를 들어, 아래 secretly_ugly_function인 경우 valueoperation 매개변수에 사용할 인자들의 자료형을 함수의 본체를 들여다보기 전까지는 전혀 알 수 없다.

아래 ugly_function 또한 여전히 부자연스럽다.

왜냐하면 둘째 매개변수 operation에 할당될 수 있는 함수는 인자로 str, int, float, bool 중의 하나의 자료형을 받아들일 수 있기 때문이다. 그래도 이렇게 자료형을 명시하면 사용자들이 프로그램을 보다 쉽게 이해할 수 있도록 도와준다.

주의: Union은 합집합을 나타내는 기호이다.

넷째, 소스코드 에디터의 자동완성 기능을 보다 적절하게 지원하게 만들어 주며, 따라서 보다 빠르게 오류 없는 프로그램을 작성할 수 있도록 도와준다.

예를 들어, VSCode 에디터에서 아래 코드를 작성하다 보면 매개변수 xs가 정수들의 리스트를 입력받을 것으로 기대하며, 리스트의 메소드의 목록을 보여주며 코드 작성을 도와주려 시도한다. (구글 코랩은 아직 지원하지 않음.)

자료형 명시 방법

변수 자료형 명시

변수의 자료형도 명시할 수 있다.

경우에 따라 변수의 자료형이 명확하지 않아서 자료형을 명시하면 많은 도움을 받을 수 있다. 예를 들어, 아래 두 변수는 어떤 종류의 리스트인지 명확하지 않다.

대신에 아래의 경우는 아주 명확하다. 즉, 빈 리스트이면서 정수들의 리스트 중에 하나임을 명확히 보여준다.

Optional 자료형

아래의 경우는 애매함이 더욱 심하다.

None은 '아무 값도 아니다'를 가리키는 '값'이다. 하지만 변수는 어떤 값을 가리키기 위해 존재하며, 새로운 값을 언제라도 가리킬 수 있다. 따라서 None이 언제라도 다른 값으로 대체될 수 있으며, 대체될 값의 자료형을 암시해줄 필요가 있다. 이를 위해 옵셔널(Optional) 자료형을 List 자료형과 유사한 방법으로 활용할 수 있다.

위와 같이 하면 best_so_far 변수에는 실수(float) 자료형이 할당될 것으로 기대함을 바로 알 수 있다. 즉, float 자료형 또는 None 값을 위해 best_so_far 변수를 사용할 것이라고 명시하는 것이다.

typing 모듈

타이핑(typing)은 List, Optional 이외에도 다른 많은 자료형을 포함하고 있다. 그중에 일부만 다룰 예정이다.

counts 변수는 문자열을 키(key)로, 정수를 키값으로 사용하는 사전 자료형을 담고 있다.

evens 변수는 0부터 9사이의 짝수를 소극적(lazy) 리스트로 담고 있다.

triple 변수는 정수, 실수, 정수 세 개의 값을 갖는 튜플이다.

Callable 함수의 자료형

파이썬에서 함수는 제1종 객체이다. 즉, 함수의 인자로 함수를 입력할 수 있다. 따라서 함수를 가리키는 매개변수의 자료형도 명시할 수 있어야 한다. 이를 위해 Callable(호출가능한) 자료형을 활용한다.

예를 들어, 아래 함수 comma_repeatertwice 함수의 인자로 입력해보자.

twice(comma_repeater, "type hints")comma_repeater("type hints", 2)의 반환값을 반환한다.

자료형도 파이썬 객체이다!

자료형을 명시하기 위해 사용된 자료형들 자체도 파이썬 객체이다. 즉, 변수에 할당할 수 있는 값으로 사용될 수 있다.

예를 들어, 복잡한 자료형을 단순한 이름으로 지정하여 다시 자료형 명시를 위해 사용할 수 있다.