리스트를 기반으로 하는 컴프리헨션을 알아보도록 하겠다.
만약 [1, 2, 3, 4, 5]
의 모든 값을 두 배씩 증가시킨 값을 갖는 리스트를 만든다고 한다면,
for문을 사용해 다음과 같이 만들 수 있다.
r1 = [1, 2, 3, 4, 5]
r2 = [] # 새로운 리스트 생성
for i in r1: # 반복문을 돌며 리스트에 요소값을 담음
r2.append(i*2)
print(r2)
# 결과
[2, 4, 6, 8, 10]
위와 같은 방법에서는 리스트의 생성과 리스트를 채우는 과정이 분리되어있다.
이때 리스트의 생성과 리스트에 채울 데이터들을 가공, 생성 ,추출해주는 과정을 하나로 묶기 위해 리스트 컴프리헨션이 존재한다.
위에서 작성했던 코드를 리스트 컴프리헨션을 사용하여 for 반복문을 사용하지 않는 형태로 대신할 수 있다.
r1 = [1, 2, 3, 4, 5]
r2 = [x*2 for x in r1] # 리스트 컴프리헨션의 기본구조
print(r2)
# 결과
[2, 4, 6, 8, 10]
리스트 컴프리헨션의 구조를 분석할때는 for
를 기준으로 왼쪽과 오른쪽으로 나눠 해석하는 것이 좋다.
왼쪽은 해당 리스트를 채울 값들에 대한 정보를 담고 있고,
오른쪽은 그 안에 있는 세세한 정보를 담고있다고 생각하면 된다.
리스트에 담을 값을 걸러내야 하는 조건이 붙는다면,
for 반복문을 사용해 다음과 같이 만들 수 있을 것이다.
r1 = [1, 2, 3, 4, 5]
r2 = []
for i in r1:
if i % 2: # i가 홀수일 경우 조건 추가
r2.append(i*2)
print(r2)
# 결과
[2, 6, 10]
위와 같이 값을 걸러내는 과정을 리스트 컴프리헨션을 이용해 어떻게 사용할 수 있는지 알아보도록 하겠다.
r1 = [1, 2, 3, 4, 5]
r2 = [x*2 for i in r1 if x%2] # if절이 추가된 리스트 컴프리헨션
print(r2)
# 결과
[2, 6, 10]
이때 for
과 if
를 기준으로 나누어서 이해하는 것이 좋다.
"x*2
를 리스트에 담는데, 이 x
는 r1
에서 하나씩 꺼내온다. 이때 x%2
가 True
일 경우에만 꺼내온다" 라고 해석할 수 있다.
r1 = ['black', 'white']
r2 = ['red', 'blue', 'green']
r3 = [t+p for t in r1 for p in r2] # 중첩된 for 반복문 형태의 리스트 컴프리헨션
print(r3)
# 결과
['blackred', 'blackblue', 'blackgreen', 'whitered', 'whiteblue', 'whitegreen']
위 코드를 다음과 같이 해석해 볼 수 있다.
리스트에 t+p
라는 값이 담기고, 여기서 t
는 r1
에서 하나씩 p
는 r2
에서 하나씩 가져오는데, t+p
의 모든 조합이 리스트에 담긴다.
이중 for 반복문 기반의 리스트 컴프리헨션에도 if절을 추가할 수 있다.
예를 들어 구구단의 결과를 담는 리스트를 만드는 과정에서 그 결과가 홀수인 값들만 리스트에 포함시킬 경우를 생각해보자.
리스트 컴프리헨션을 사용하여 코드를 작성하면 다음과 같다.
r = [n*m for n in range(2,10) for m in range(1,10) if (n*m) % 2]
print(r)
# 결과
[3, 9, 15 ,21, 27, 5, 15, 25, 35, 45, 7, 21, 35, 49, 63, 9, 27, 45, 63, 81]
n*m
이 리스트에 담기는데, 여기서 n
은 2, 3, ..., 9
를 하나씩 가져오고, m
은 1, 2, 3, ..., 9
를 하나씩 가져온다. 단 n*m
을 2로 나누었을때 나머지가 있는, 즉 if절에 True
값을 갖는 홀수만이 리스트에 담긴다고 해석할 수 있다.
🔎 참고
중급편 열혈 파이썬 story04