Skip to content

Latest commit

 

History

History

Chapter08

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

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

리스트 컴프리헨션은 기본 사용법뿐만 아니라 다중 루프도 지원한다.

아래는 행렬을 모든 셀이 포함된 평평한 리스트로 간략화 한다고 할 때, for 표현식 두 개를 사용한 리스트 컴프리헨션이다.

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]

이 표현식은 __왼쪽에서 오른쪽 순서__로 실행된다.

다중 루프의 또 다른 합당한 사용법은 __입력 리스트의 레이아웃을 두 레벨로 중복__해서 구성하는 것이다.

예를 들어 2차원의 행렬에 각 셀에 있는 값의 제곱근은 두한다고 할 때 아래와 같이 표현할 수 있다.

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
squared = [[x**2 for x in row] for row in matrix]
print(squared)

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

레이아웃을 중복해서 구성하기위해 추가로 [] 문자를 사용하였다.

처음 예제와는 달리 셀을 평평한 리스트로 만든 것이 아니다.

이 표현식을 다른 루프에 넣는다면 리스트 컴프리헨션이 여러 줄로 구분할 정도로 길어진다.

my_lists = [
    [[1, 2, 3], [4, 5, 6]],
    # ...
]
flat = [x for sublist1 in my_lists
        for sublist2 in sublist1
        for x in sublist2]
print(flat)

>>>
[1, 2, 3, 4, 5, 6]

이제 여러 줄짜리 컴프리헨션이 다른 방법보다 많이 짧지는 않다.

일반 루프문으로 같은 결과를 만들어보자.

my_lists = [
    [[1, 2, 3], [4, 5, 6]],
    # ...
]
flat = []
for sublist1 in my_lists:
    for sublist2 in sublist1:
        flat.extend(sublist2)
print(flat)

>>>
[1, 2, 3, 4, 5, 6]

큰 차이는 없지만 리스트 컴프리헨션보다 이해하기 쉽다.


리스트 컴프리헨션도 다중 if 조건을 지원하는데, 여러 조건이 있는 경우는 암시적으로 and 표현식이 된다.

예를 들어 리스트에서 4보다 큰 짝수만 구한다면 아래 두 컴프리헨션은 동일하다.

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = [x for x in a if x > 4 if x % 2 == 0]
c = [x for x in a if x > 4 and x % 2 == 0]

조건은 루프의 각 레벨에서 for 표현식 뒤에 설정할 수 있다.

행렬에서 row의 합이 10 이상이고 3으로 나누어 떨어지는 셀을 구한다면 아래와 같이 표현할 수 있다.

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
filtered = [[x for x in row if x % 3 == 0]
            for row in matrix if sum(row) >= 10]
print(filtered)

>>>
[[6], [9]]

이런 코드는 다른 사람들이 이해하기 매우 어렵다.

리스트 컴프리헨션을 사용할 때는 표현식이 두 개를 넘어가면 피하는 게 좋다.


이것보다 복잡해지면 if 문과 of for 문을 사용하고 헬퍼 함수를 사용해서 작성하도록한다.
*개인적으로 예제 수준은 크게 가독성이 떨어지는 것 같진 않다..*

더 복잡해지면 가독성이 떨어질 수 있기 때문에 for, if 또는 헬퍼 함수를 사용하자..


## 핵심 정리 1. 리스트 컴프리헨션은 다중 루프와 레벨별 다중 조건을 지원한다.
  1. 표현식이 두 개가 넘어가는 리스트 컴프리헨션은 가독성이 떨어지므로 피하자.