Comprehension
컴프리헨션(Comprehension)은 “이해”와 관련된 영단어 Comprehend에서 유래했다. 이름에서 알 수 있듯, 파이썬에서는 컴프리헨션을 통해 보다 간결(Concise)하고 가독성이 좋은(Readable, Expressive) 코드를 작성할 수 있다.
컴프리헨션 종류
•
List
•
Set
•
Dictionary
장점
•
코드가 짧아지고 간결해진다
•
많은 경우 가독성이 좋아진다
•
단순 iteration보다 Low-level에서 보다 효율적으로 처리된다
•
Nested 하게 작성해도 코드가 많이 길어지지 않는다
짧은 코드가 항상 좋은 코드는 아니다. 클린 코드를 작성하기 위해서는 과도하게 코드의 길이를 줄이는 것은 항상 경계해야한다.
사용하는 방법
•
— for — in — 형식을 따른다
•
데이터를 변환(transformation)할 수 있다
◦
ex) 각각의 원소를 2배로 하는 새로운 리스트가 필요하다
•
데이터를 필터링(filtering)할 수 있다
◦
ex) 짝수인 원소만 뽑아서 리스트를 만들고 싶다
•
데이터를 매핑(mapping)할 수 있다
◦
ex) 독립적인 key list와 value list로 하나의 dictionary를 만들 수 있다
List Comprehension
# 원본 리스트
nums = [1, 2, 3, 4, 5]
# 각 원소를 그대로 가져오는 리스트
nums_copy = [n for n in nums] # [1, 2, 3, 4, 5]
# 각 원소를 제곱한 리스트
square_nums = [n**2 for n in nums] # [1, 4, 9, 16, 25]
# 각 원소의 짝수만 가져온 리스트
even_nums = [n for n in nums if n % 2 == 0] # [2, 4]
Python
복사
만약 컴프리헨션이 익숙하지 않다면 nums_copy를 만드는 것처럼 일단 [n for n in nums]를 입력하고 시작하자. 여기서 서두의 n을 조정하여 리스트에 담을 값을 정하고, 후미에 if문 등을 추가하여 필터링을 진행하면 편하다.
또한, 파이썬이 제공하는 유용한 기능인 Pack, Unpack을 이용하면 하나 이상의 변수를 이용할 수도 있다.
# [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
idx_num_pair = [(idx, n) for idx, n in enumerate(nums)]
Python
복사
Set Comprehension
만약 List Comprehension을 사용하는 것에 익숙해졌다면 대괄호를 다른 괄호로 바꿈으로써 다른 객체를 얻을 수 있다. Set을 얻고 싶다면 [ ] 대신 { }를 사용한다.
squares_set = {x**2 for x in range(10)}
print(squares_set) # {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}
Python
복사
Dictionary Comprehension
Dictionary객체는 Key-Value Pair를 갖기 때문에 값을 지정하는 부분에 key : value 형식으로 지정해 주면 된다. 굉장히 직관적이다.
words = ['안녕하세요', '제', '이름은', '비밀']
word_lengths = {name: len(name) for name in words}
print(word_lengths) # {'안녕하세요': 5, '제': 1, '이름은': 3, '비밀': 2}
Python
복사
Generator: genexpr
그렇다면 만약 아무 괄호가 없는 표현식은 어떻게 처리 될까? 파이썬은 genexpr라는 제너레이터 객체를 생성한다.
implicit_expr = (x for x in [1, 2, 3, 4, 5])
print(implicit_expr) # <generator object <genexpr> at 0x00000289750179E0>
Python
복사
그리고 이 제너레이터를 이용하여 다른 이터러블 객체를 생성할 수 있다. 참고로 재사용은 불가능하다
# 튜플
print(tuple(implicit_expr)) # (1, 2, 3, 4, 5)
print(tuple(implicit_expr)) # ()
Python
복사
# 리스트
print(list(implicit_expr)) # [1, 2, 3, 4, 5]
Python
복사
# 집합
print(set(implicit_expr)) # {1, 2, 3, 4, 5}
Python
복사
Tuple Comprehension
Python 3.5이후부터는 Generator과 Unpack 기능(*)을 사용하여 Tuple Comprehension과 같은 방식을 유도할 수 있다(실제로 튜플 컴프리헨션은 없다).
먼저 다음 코드를 보자
# 튜플 ?
tup = (1)
print(tup) # 1
Python
복사
튜플을 만들 생각으로 ( )로 숫자를 감쌌지만, 해당 소괄호는 연산의 우선순위를 위한 용도로 사용되었고 튜플을 만들지는 않았다. 원소가 두 개 이상이라면 정상적으로 튜플 객체를 만든다.
# 튜플 !
tup = (1, 2)
print(tup) # (1, 2)
Python
복사
그렇다면 원소가 하나인 튜플은 어떻게 표현할까? 바로 하나의 콤마를 이용한다.
one_tuple = tuple([1])
print(one_tuple) # (1,)
Python
복사
그리고 *를 통해 튜플의 값을 Unpacking 할 수 있다.
print(*one_tuple) # 1
Python
복사
이 기능을 종합하면 다음과 같은 표현식으로 튜플 객체를 생성할 수 있다.
comp_tuple = *(n for n in range(5)),
print(comp_tuple) # (0, 1, 2, 3, 4)
print(type(comp_tuple)) # <class 'tuple'>
Python
복사