본문 바로가기
Python

[Python] 리스트 컴프리헨션(list comprehension)

by yu901 2021. 10. 12.

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


 

파이썬에는 한 리스트에서 다른 리스트를 만들어내는 간결한 문법이 있다. 이 문법을 사용한 표현식을 리스트 컴프리헨션(list comprehension; 리스트 함축 표현식)이라고 한다.

 

# example 1: 리스트에 있는 각 숫자의 제곱을 계산
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
squares = [x**2 for x in a]
print(squares)

>>>
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

 

 

리스트 컴프리헨션은 내장함수 map, filter를 사용하는 것보다 명확하다.

 

# example 2: 2로 나누어 떨어지는 숫자의 제곱만 계산
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# list comprehension
even_squares = [x**2 for x in a if x % 2 == 0]

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

print(even_squares)

>>>
[4, 16, 36, 64, 100]

 

 

딕셔너리와 세트도 컴프리헨션 표현식을 지원한다.

 

# example 3: key-value 변경한 딕셔너리, value 길이 세트
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)
print(chile_len_set)

>>>
{1: 'ghost', 2: 'habanero', 3: 'cayenne'}
{8, 5, 7}

 

 

 

BETTER WAY 8 리스트 컴프리헨션에서 표현식 두 개 넘게 쓰지 말자


 

리스트 컴프리헨션은 다중 루프를 지원한다. 표현식은 왼쪽에서 오른쪽 순서로 실행된다.

 

# example 4: 행렬을 모든 셀이 포함된 평평한 리스트 하나로 간략화
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [x for row in matrix for x in row]
print(flat)

>>>
[1, 2, 3, 4, 5, 6, 7, 8, 9]

 

 

리스트 컴프리헨션은 다중 if 조건을 지원한다.

 

# example 5: 4보다 큰 짝수 값만 필터
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
filtered = [x for x in a if x > 4 if x % 2 == 0]
filtered = [x for x in a if x > 4 and x % 2 == 0]
print(filtered)

>>>
[6, 8, 10]

 

 

리스트 컴프리헨션을 사용할 때는 표현식이 두 개를 넘어가면 피하는 게 좋다. 이것보다 복잡해지면 일반적인 if 문과 for 문을 사용하고 헬퍼 함수를 작성해야 한다.

 

# example 6: 다차원 행렬을 평평한 리스트 하나로 간략화
my_list = [
    [[1, 2, 3,], [4, 5, 6],
    # ...
]

# list comprehension
flat = [x for sublists1 in my_lists
        for sublist2 in sublist1
        for x in sublist2]
        
# for statement
flat = []
for sublist1 in my_lists:
    for sublist2 in sublist1:
        flat.extend(sublist2)

 

 

 

BETTER WAY 9 컴프리헨션이 클 때는 제너레이터 표현식을 고려하자


 

리스트 컴프리헨션의 문제점은 입력 시퀀스에 있는 각 값 별로 아이템을 하나씩 담는 새 리스트를 생성하는 것이다. 파이썬은 이 문제를 해결하려고 리스트 컴프리헨션과 제너레이터를 일반화한 제너레이터 표현식(generator expression)을 제공한다. 제너레티터 표현식은 이터레이터(iterator)로 한 번에 한 출력만 만드므로 메모리 문제를 피할 수 있다.

의 문제점은 한다는 점이다.

 

# example 7: 파일을 읽고 각 줄에 있는 문자의 개수를 반환
# list comprehension
value = [len(x) for x in open('/tmp/my_file.txt')]
print('list comprehension:', value)

# generator
it = (len(x) for x in open('/tmp/my_file.txt'))
print('generator:', it)
print(next(it))
print(next(it))

>>>
list comprehension: [100, 57, 15, 1, 12, 75, 5, 86, 89, 11]
generator: <generator object <genexpr> at 0x101b81480>
100
57

 

 

 


출처

  • 브렛 슬라킨, 파이썬 코딩의 기술 (길벗, 2019)

댓글