강의 개요

  • 강의명: 머신러닝을 위한 파이썬
  • 교수: 최성철
  • 제작: 네이버 부스트코스

파이썬 스타일 코드

파이썬은 다른 언어과 차별화되는 독특한 스타일을 가지고 있다. 그리고 그 스타일 덕분에 쉽고 직관적인 코드 작성이 가능하다.

다음은 텍스트를 합치는 일반적인 코드 작성법이다.

colors = ["a", "b", "c", "d"]
result = ''
for s in colors:
    result += s

그러나 좀 더 파이썬스럽게 작성하면 다음처럼 쓸 수 있다.

colors = ["a", "b", "c", "d"]
result = ''.join(colors)

좀 더 간결하다! 이처럼 파이썬 특유의 기법으로 코드를 더 간단하게 작성할 수 있으며, 고급 코드를 사용할수록 더 필요하다. 특히 많은 사람들이 이런 파이썬스러운 코드를 작성하고 있기 때문에 다른 사람의 코드를 이해하기 위해서도 알아두어야 한다.

대표적인 파이썬스러운 코딩 방식은 다음과 같다.

  • split & join
  • list comprehension
  • enumerate & zip


split과 join

문자열을 쪼갤 때 split()을 사용한다.

>>> items = "a b c d".split()   # 빈칸을 기준으로 나누기
>>> print(items)
['a', 'b', 'c', 'd']
>>> example = "a, b, c, d"
>>> example.split(", ")         # ", "를 기준으로 나누기
['a', 'b', 'c', 'd']
>>> a, b, c, d = example.split(", ")
>>> print(a, b, c, d)
a b c d

기본적으로는 빈칸을 기준으로 나누며, ‘,’처럼 나눌 기준을 지정할 수도 있다.

문자열을 합칠 때는 join()을 사용한다.

>>> items = "a b c d".split()
>>> result = ''.join(items)
>>> print(result)
'abcd'
>>> result = ",".join(items)
>>> print(result)
'a,b,c,d'

join() 앞에 연결에 사용할 문자를 지정해줄 수도 있다.


List comprehension

List comprehension은 리스트만을 이용해서 다른 리스트를 간단히 만드는 방법이다. 물론 반복문과 append를 사용할 수도 있지만, 보통 list comprehension이 조금 더 빠르다.

>>> result = [i for i in range(10)]
>>> print(result)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

조건을 넣어줄 수도 있다!

>>> result = [i for i in range(10) if i % 2 == 0]
>>> print(result)
[0, 2, 4, 6, 8]

조금 헷갈리지만 유용하게 사용할 수 있는 기법으로 이중 list comprehension이 있다. 먼저, 이중 괄호가 없는 경우부터 살펴보자.

>>> word_1 = "Hello"
>>> word_2 = "World"
>>> result = [i+j for i in word_1 for j in word_2]
>>> print(result)
['HW', 'Ho', 'Hr', 'Hl', 'Hd', 'eW', 'eo', 'er', 'el', 'ed', 'lW', 'lo', 'lr', 'll', 'ld', 'lW', 'lo', 'lr', 'll', 'ld', 'oW', 'oo', 'or', 'ol', 'od'] 

이는 다음과 같은 이중 for 루프와 동일한 효과를 낸다.

for i in word_1:
    for j in word_2:
        i + j

이제 비슷하지만 다른 list comprehension을 보자. 괄호가 두 겹이다.

>>> result = [[i+j for j in word_2] for i in word_1]
>>> print(result)
[['HW', 'Ho', 'Hr', 'Hl', 'Hd'], ['eW', 'eo', 'er', 'el', 'ed'], ['lW', 'lo', 'lr', 'll', 'ld'], ['lW', 'lo', 'lr', 'll', 'ld'], ['oW', 'oo', 'or', 'ol', 'od']]

다른 점이 보이는가? 일단 결과가 2차원의 리스트이다. 원리를 설명하면, 먼저 바깥에 있는 word_1을 고정(fix)시킨 뒤, 내부에 있는 for문을 돌리는 것이다.

1차원의 결과와 2차원 결과의 차이를 아는 것이 중요하다.


enumerate와 zip

enumerate()는 리스트의 요소들을 추출할 때, 그 인덱스를 붙여서 추출한다.

>>> for i, v in enumerate(['a', 'b', 'c']):
...     print(i, v)
... 
0 a
1 b
2 c

enumerate()를 잘 활용하면 인덱스를 키(key)로 하는 딕셔너리를 만들 수도 있다.

>>> {i:j for i, j in enumerate("Hello World !".split())}
{0: 'Hello', 1: 'World', 2: '!'}

zip()은 같은 인덱스에 위치한 값을 병렬적으로 추출해서 묶는다.

>>> list_a = ['a', 'b', 'c']
>>> list_b = ['ㄱ', 'ㄴ', 'ㄷ']
>>> for a, b in zip(list_a, list_b):
...     print(a, b)
... 
a 
b 
c 

같은 위치의 값을 합하는 프로그램을 만들어보자.

>>> [sum(x) for x in zip((1, 2, 3), (10, 20, 30), (100, 200, 300))]
[111, 222, 333]

이번에는 enumerate와 zip을 동시에 사용해보자.

>>> list_a = ['a', 'b', 'c']
>>> list_b = ['ㄱ', 'ㄴ', 'ㄷ']
>>> for i, (a, b) in enumerate(zip(list_a, list_b)):
...     print(i, a, b)
... 
0 a 
1 b 
2 c 


람다(lambda) 함수

람다(lambda)함수는 함수의 이름을 지을 필요 없이 간단하게 사용할 수 있는 익명 함수이다. 보통 파이썬에서는 def를 사용해서 함수를 정의하지만, 한 번 쓰고 버릴 함수까지 이렇게 정의하면 매우 번거로울 것이다. 따라서 람다 함수로 일회용 함수를 만든다.

def f(x, y):
    return x + y

f = lambda x, y: x + y

위 두 함수는 기본적으로 동일한 기능을 한다.

Python3 부터는 람다 함수가 권장되지 않는다. List comprehension 등으로도 충분히 구현할 수 있기 때문이다. 그러나 판다스 등에서는 여전히 유용하게 사용되므로 알아두는 것이 좋다.


map, reduce

map()은 sequence 자료형의 각 요소에 동일한 함수를 적용한다. 아마 백준을 하면서 질리도록 썼을 것이다 사용법은 map(function_name, list_data)처럼 쓰면 된다. 두 개 이상의 리스트에도 map(function_name, list_data, list_data)처럼 적용이 가능하다. map()으로 리스트를 만들기 위해서는 꼭 list()로 감싸주어야 한다.

reduce()는 계산을 계속 누적해준다고 생각하면 쉽다. 다음과 같이 사용한다.

>>> from functools import reduce
>>> print(reduce(lambda x, y: x + y, [1, 2, 3, 4, 5]))
15

(1 + 2)를 하고, 그 값인 3에 다시 3을 더하고, 다시 4를 더하고… 이렇게 계산된다. 팩토리얼을 구할 때 사용하면 매우 유용할 것이다.



별도의 출처 표시가 있는 이미지를 제외한 모든 이미지는 강의자료에서 발췌하였음을 밝힙니다.

댓글남기기