리스트 컴프리헨션이란?
파이썬에서 제공하는 기능으로 리스트를 간결하고 가독성 높게 생성할 수 있는 방법입니다.
목차
- 리스트 컴프리헨션의 편리성
- 리스트 컴프리헨션의 문법
- * 연산자을 배열에서 사용하면 안 되는 이유
1. 리스트 컴프리헨션의 편리성
리스트 컴프리헨션을 처음 접하시는 분이라면 for을 이용해서 리스트를 문제없이 잘 만들고 있었는데 왜 내가 이걸 써야 하지?라는 의문을 가지실 수 있습니다.
코드 두 개를 비교해 보겠습니다.
list_without_comprehension = []
for _ in range(3):
inner_list = []
for _ in range(5):
inner_list.append(0)
list_without_comprehension.append(inner_list)
print(list_without_comprehension)
파이썬을 하시는 분이라면 간단히 이해하실 수 있는 코드입니다.
이중 반복문을 통해 inner_list에 0이라는 숫자를 5번 추가한 후, list_without_comprehension이라는 리스트에 3번 추가하는 방법이죠.
list_comprehension = [[0] * 5 for _ in range(3)]
print(list_comprehension)
위 코드는 리스트 컴프리헨션을 사용해서 이전의 코드와 똑같은 리스트를 생성하는 코드입니다.
이전의 코드는 리스트를 만드는데 6줄이 필요했으나, 리스트 컴프리헨션을 사용하면 한 줄로 충분합니다.
2. 리스트 컴프리헨션의 문법
1. 표현식 + for
리스트의 각 요소에 대해 표현식을 적용해서 리스트를 생성할 수 있습니다.
result = [i*2 for i in range(5)]
# 결과: [0, 2, 4, 6, 8]
2. 표현식 + for + 조건문
if문을 만족하는 요소만 리스트에 추가됩니다.
result = [i*2 for i in range(10) if i % 2 == 0]
# 결과: [0, 4, 8, 12, 16]
3. 조건문 + for
주어진 조건에 따라 다른 값을 반환합니다.
2번은 조건문을 만족하는 요소만 리스트에 들어갔다면 3번은 조건문에 따라 다른 요소가 들어갑니다.
result = ['even' if i % 2 == 0 else 'odd' for i in range(5)]
# 결과: ['even', 'odd', 'even', 'odd', 'even']
4. 중첩 for문
중첩된 루프를 한 줄로 표현할 수 있습니다.
result = [(x,y) for x in [1,2] for y in ['a','b']]
# 결과: [(1,'a'), (1,'b'), (2,'a'), (2,'b')]
3. * 연산자를 배열에서 사용하면 안 되는 이유
list1 = [[0] * 5] * 3
list2 = [[0] * 5 for _ in range(3)]
list1[1][1] = 99
list2[1][1] = 99
print(list1)
print(list2)
문제: list1과 list2를 출력했을 때 차이가 있을까?
결과부터 말하면 있다!
대부분의 프로그래머들은 list1, list2의 결과값을 (1,1)에 위치한 요소만 99로 바뀐 값으로 예상할 것이다.
list1 = [[0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0]]
list2 = [[0, 0 , 0 , 00 ], [00 ,99 ,00 ,00 ], [00 ,00 ,00 ,00 ]]
#list1 = , list2 = 는 편의를 위해 추가한 문자열입니다.
list1을 보면 99라는 숫자가 3개 있는 모습을 볼 수 있다.
list1과 list2를 만들 때의 차이점은 * 연산을 이용해서 배열을 3개로 늘린 것과 리스트 컴프리헨션을 사용해서 늘린 것이다.
**지금부터 집중하셔야 됩니다. **
파이썬은 다른 언어와 다르게 리스트에 요소의 값을 저장하지 않고 요소의 값이 있는 곳의 주소를 저장합니다.
그러므로 * 연산자를 이용해서 리스트를 늘리게 된다면 메모리 주소값들이 복사가 되어 동일한 데이터로 취급됩니다.
그래서 list1의 결과값을 보면 99가 3개 생긴 것입니다.