본문 바로가기

Python

리스트 컴프리헨션(list comprehension)

1
2
3
4
5
6
7
8
# 왼쪽에서 오른쪽으로 진행되면서 실행된다. 
matrix = [[1,2,3], [4,5,6], [7,8,9]]
print(matrix)
matrix_row_element = [row_element for row in matrix for row_element in row]
print(matrix_row_element)
 
[[123], [456], [789]]
[123456789]
cs

리스트 컴프리헨션 자꾸 까먹어서 정리할 겸.

처음 for 앞에 있는 row_element는 당연하겠지만 두번째 for 뒤에 있는 row_element와 같다. 

일반적으로 리스트 컴프리핸션 실행 순서는 왼쪽에서 오른쪽.

행(row)가 matrix를 반복하면서 row_element는 row를 반복. 그리고 그걸 순차적으로 끄집어 낸다. 

괄호는 두 번 벗겨(?)내어 원소를 끄집어 내기 위해 for문을 두번 돌린다. 

 

1
2
3
4
5
6
7
8
9
10
# for문 3개인 경우
 
matrix = [[[1,2,3], [4,5,6], [7,8,9]], [['a','b','c'], ['d''e''f']]]
 
sub_matrix_list_element = [element for sub_matrix in matrix
                                   for sub_matrix_list in sub_matrix
                                   for element in sub_matrix_list]
print(sub_matrix_list_element)
 
[123456789'a''b''c''d''e''f']
cs

그렇다면 위 matrix와 같은 경우는 3개의 for 문을 사용한다. 

 

1
2
3
4
5
6
7
8
# 다중리스트 제곱하기
 
matrix = [[1,2,3], [4,5,6], [7,8,9]]
squared_matrix = [[x**2 for x in matrix_list]
               for matrix_list in matrix]
print(squared_matrix)
 
[[149], [162536], [496481]]
cs

다만 일반적으로 왼쪽에서 오른쪽으로 실행되는 리스트 컴프리핸션에서 괄호 두개가 사용될 경우 오른쪽에서 왼쪽으로 실행된다. 

 

1
2
3
4
5
6
7
8
9
= [12345678910]
= [x for x in a if x > 4 if x % 2 == 0]
= [x for x in a if x > 4 and x % 2 == 0]
 
print(b)
print(b)
 
[6810]
[6810]
cs

조건식을 지정해서 그에 맞는 x를 골라낼 수도 있다. 

c는 x가 4보다 크고 2로 나누었을 때 0인 숫자를 반환한다. 

 

1
2
3
4
5
6
7
8
# 행렬에서 행(row)의 합이 10 이상이고 3으로 나누어 떨어지는 셀을 구하기
 
matrix = [[123], [456], [789], [101112], [131415]]
filtered = [[x for x in row if x % 3 == 0]
               for row in matrix if sum(row) >= 10]
print(filtered)
 
[[6], [9], [12], [15]]
cs

조금 더 복잡하게 행렬에서 행(row)의 합이 10 이상이고 3으로 나누어 떨어지는 셀을 구하기의 경우에는 위와 같다.