지능형 리스트라고 번역하면 그나마 알맞을 듯하다. 리스트 축약이라고 쓰시는 분도 있는 것 같은데, 그냥 우리는 리스트 컴프리헨션이라고 쓰자.
사용법은 간단하다.
“안녕!” 이 들은 리스트를 3개 만들고 싶다.
1
a = [["안녕!"] for \_ in range(3)]
어? for의 원소에 언더바 하나만 있네? 아무 문제 없다. 저기에 n이 들어가건 i가 들어가건 저 언더바 하나로 처리되는 건 동일하다. 이제 출력해보자.
1
[['안녕!'], ['안녕!'], ['안녕!']]
하지만 기분이 바뀌었다. 나는 갑자기 한 리스트에 3개의 안녕을 집어넣고 싶어졌다.
1
a = [["안녕!"] \* 3 for \_ in range(3)]
이제 또다시 출력해보자.
1
[['안녕!', '안녕!', '안녕!'], ['안녕!', '안녕!', '안녕!'], ['안녕!', '안녕!', '안녕!']]
아주 간단하다. 이게 전부다! 이것만 알면 우리는 뭐든 할 수 있는 것이다.
어? 왜 그렇게 불편하게 for문을 돌려? 이렇게 하면 되잖아?
1
b = [["안녕!"] \* 3] \* 3
바보 아냐? 똑같은 답이 출력되는데 뭐 그렇게 힘들게 반복되는 일을 해? 라고 생각할 수도 있겠지만,
자, 중요한 건 지금부터다.
1
2
3
a[0][1] = "나는"
a[0][2] = "루네체"
print(a)
보나마나 뻔한 결과가 나올 것이다. 안녕 나는 루네체 이후 계속 쭉 안녕이 출력될 것이다. 결괏값을 보자.
1
[['안녕!', '나는', '루네체'], ['안녕!', '안녕!', '안녕!'], ['안녕!', '안녕!', '안녕!']]
자, 그런데 b는 저렇게 하면 어떻게 바꿔야 하는가? 방법이 없다. 하는 수 없지. a랑 똑같이 C&P해보자.
1
2
3
b[0][1] = "너는"
b[0][2] = "스노우"
print(b)
하지만 결괏값은 너무나도 다르다.
1
[['안녕!', '너는', '스노우'], ['안녕!', '너는', '스노우'], ['안녕!', '너는', '스노우']]
아, 이런 결과가 나오네? 그럼 인덱스 값만 새로 바꿔오면 음…가능하지 않을까?
1
2
3
4
5
6
b[0][1] = "너는"
b[0][2] = "스노우"
print(b)
b[1][1] = "나는"
b[1][2] = "루네체"
print(b)
자 이제 돌려보자!
1
2
[['안녕!', '너는', '스노우'], ['안녕!', '너는', '스노우'], ['안녕!', '너는', '스노우']]
[['안녕!', '나는', '루네체'], ['안녕!', '나는', '루네체'], ['안녕!', '나는', '루네체']]
이런 결과가 나오게 된다. 먼저 스노우가 써지고, 그 위에 루네체가 그대로 덮어버린 것이다. 인덱스만 받아오는 것은 완전히 실패했다.
이것에서 보듯이 리스트 컴프리헨션은 매우 간단하면서도 우리의 데이터를 안전하게 관리할 수 있다는 사실을 알았다.
이제 리스트 컴프리헨션을 이용하여 연산을 해볼 시간이다.
1
2
firstList = ["1", "2", "3", "4", "5"]
secondList = ["6", "7", "8", "9", "10"]
위 두 개의 리스트를 각각의 열에 맞춰 더한 뒤 새로운 리스트에 넣는다. 단, 리스트 컴프리헨션을 쓰지 않고 하는 법과 쓰는 법을 모두 사용해야만 한다. 어떻게 해야 할까?
일단 리스트 컴프리헨션 없이 해보자.
1
2
3
4
newList = []
for i, j in zip(firstList, secondList):
newList.append(i + j)
print(newList)
여기서는 zip 함수를 쓴다. zip 메소드는 같은 인덱스를 가진 두 개의 리스트를 하나로 합쳐준다.
두 리스트를 해당하는 열마다 합친 뒤 새로운 리스트에 추가한다.
1
[7, 9, 11, 13, 15]
그렇다면 이것을 리스트 컴프리헨션으로 한다면?
리스트 컴프리헨션을 요약하자면 다음과 같다. [연산 반복문] 연산 반복문. 이게 전부다. 이것을 이해하기 쉽게 적어보자.
1
newList = [i + j for i, j in zip(firstList, secondList)]
아까의 for문 중 첫 줄이 바로 반복문, 두 번째 연산문이 바로 연산에 들어가면 되는 것이다. 결괏값은 같다.
문제를 하나 더 풀어보자.
이번에는 언패킹을 하지 않고 아래의 리스트를 하나의 리스트로 정렬할 것이다.
1
a = [["1", "2", "3"], ["4", "5"]]
먼저 for문을 이용해 풀어보자.
1
2
3
for i in a:
for j in i:
print(j)
이렇게 하면 1부터 5까지 차례대로 정렬이 된다. 이제 프린트문을 지우고 새로운 리스트를 만들자.
1
2
3
4
5
6
a = [["1", "2", "3"], ["4", "5"]]
newList = []
for i in a:
for j in i:
newList.append(j)
print(newList)
1
['1', '2', '3', '4', '5']
이것을 리스트 컴프리헨션으로 한다면?
똑같이 하면 된다.
1
newList = [j for i in a for j in i]