[Python Chapter1 08]
in Python on EffectivePython
본 포스팅은
파이썬코딩의기술
이라는 책을 참고하여 개인 공부를 하면서 정리하고 있습니다.문제 될 시 삭제하겠습니다.
Chapter 1
8. 리스트 컴프리헨션에서 표현식을 두 개 넘게 쓰지 말자
- 기본 리스트 컴프리헨션 뿐만 아니라 다중 루프도 지원한다.
- 다중 루프란?
루프
라는 용어는 반복을 의미하고다중
은 여러 개가 겹치는 것을 의미함 - 즉, 반복문 여러 개가 겹쳐 있는 구조를 말함
- 다중 루프란?
# 행렬을 모든 셀이 포함된 평평한 리스트 하나로 간략화한다고 가정
# 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)을 정의하기 전에 배열부터 알아보자
배열(array)이란?
- 컴퓨터 언어에서 여러 종류의 데이터의 묶음을 의미
행렬(matrix)이란?
이들 중 다차원으로 수를 묶은 것을 의미
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] # 행(row)은 [1, 2, 3] [4, 5, 6] [7, 8, 9] 를 뜻하며 # 행(row) 한 줄은 괄호 하나를 벗기면 되고 # 행(row) 한 줄에 속해있는 원소들을 괄호 두 개를 벗기면 된다. # 열(column)은 [1, 2, 3], [4, 5, 6], [7, 8, 9] 를 뜻함 # 같은 열(column)에 있는 원소들을 뽑아내려면 행(row)의 위치가 같으면 됨
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]
이번엔 일반 루프문으로 같은 결과를 만들어보자
# 이 버전은 들여쓰기를 사용해서 리스트 컴프리헨션보다 이해하기 쉽다
flat = []
for sublist1 in my_lists:
for sublist2 in sublist1:
flat.extend(sublist2)
리스트 컴프리헨션도 다중 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]
>>> b와 c 둘다 [6, 8, 10]
조건은 루프의 각 레벨에서 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문과 for문을 사용하고 헬퍼 함수를 작성해야 한다
정리
- 리스트 컴프리헨션은 다중 루프와 루프 레벨별 다중 조건을 지원함
- 표현식이 두 개가 넘게 들어 있는 리스트 컴프리헨션은 이해하기 매우 어려우므로 피해야 함