EXCELSIOR

BETTER WAY 7 - map과 filter 대신 리스트 컴프리헨션을 사용하자 본문

Python/Effective Python

BETTER WAY 7 - map과 filter 대신 리스트 컴프리헨션을 사용하자

Excelsior-JH 2018. 2. 23. 16:03

BETTER WAY 7 - map과 filter 대신 리스트 컴프리헨션을 사용하자

Item07 - Use List Comprehensions Instead of map and filter

Python에서는 한 리스트에서 다른 리스트를 만들어내는 간결한 문법이 있다.
바로 리스트 컴프리헨션(list comprehension) 이라고 한다.

1
2
3
4
5
6
7
8
# List Comprehension을 이용해 루프를 돌면서 
# 아래와 같이 계산이 가능하다.
= [12345678910]
squares = [x**2 for x in a]
print(squares)
'''출력결과
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
'''
cs



이처럼 간단한 연산에는 리스트 컴프리헨션이 내장 함수 map보다 명확하다. 
map을 쓰려면 계산에 필요한 lambda 함수를 생성해야 하기 때문에 깔끔해 보이지 않는다.

1
2
3
4
5
6
squares = map(lambda x:x**2, a)
squares = list(squares)
print(squares)
'''출력결과
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
'''
cs



map과 달리 List Comprehension을 사용하면 입력 리스트에 있는 아이템(요소)을 간편하게 걸러낼 수 있다.

1
2
3
4
5
6
7
# 예를 들어 2로 나누어 떨어지는 숫자의 제곱만 계산한다고 하면 
# 아래와 같이 작성하면 된다.
even_squares = [x**2 for x in a if x % 2 == 0]
print(even_squares)
'''출력결과
[4, 16, 36, 64, 100]
'''
cs



내장 함수 filter를 map과 연계해서 사용해도 같은 결과를 얻을 수 있지만 훨씬 읽기가 어렵다.

1
2
alt = map(lambda x: x**2, filter(lambda x: x % 2 == 0, a))
assert even_squares == list(alt)
cs



딕셔너리(dictionary)와 집합(set)에도 리스트 컴프리헨션에 해당하는 문법이 있다.

1
2
3
4
5
6
7
8
9
chile_ranks = {'ghost'1'habanero'2'cayenne'3}
rank_dict = {rank: name for name, rank in chile_ranks.items()}
chile_len_set = {len(name) for name in rank_dict.values()}
print('rank_dict =', rank_dict)
print('chile_len_set =', chile_len_set)
'''출력결과
rank_dict = {1: 'ghost', 2: 'habanero', 3: 'cayenne'}
chile_len_set = {8, 5, 7}
'''
cs



정리

  • 리스트 컴프리헨션은 추가적인 lambda 표현식이 필요 없어서 내장 함수인 map이나 filter를 사용하는 것보다 명확하다.
  • 리스트 컴프리헨션을 사용하면 입력 리스트에서 아이템을 간단히 건너뛸 수 있다.
  • 딕셔너리와 세트도 컴프리헨션 표현식을 지원한다.


Comments