[Python Chapter1 08]


본 포스팅은 파이썬코딩의기술 이라는 책을 참고하여 개인 공부를 하면서 정리하고 있습니다.

문제 될 시 삭제하겠습니다.

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문을 사용하고 헬퍼 함수를 작성해야 한다

정리

  • 리스트 컴프리헨션은 다중 루프와 루프 레벨별 다중 조건을 지원함
  • 표현식이 두 개가 넘게 들어 있는 리스트 컴프리헨션은 이해하기 매우 어려우므로 피해야 함





© 2018. by Dev_Yonghee

Powered by Dev_Yong