리스트 컴프리헨션은 그냥 for문 짧게 쓰는 문법이 아니다.
코딩테스트에서는 보통
입력을 가공하거나, 조건에 맞는 값만 뽑거나, 간단한 변환을 한 줄로 처리할 때 제일 많이 쓴다.
즉, 이걸 문법 하나로만 보면 잘 안 남고,
반복 + 조건 + 변환을 한 번에 묶는 패턴으로 봐야 실전에서 손에 붙는다.
처음에는 나도 그냥 “짧게 쓰는 문법” 정도로만 봤는데,
막상 문제 풀다 보니까 이게 꽤 자주 나왔다.
- 숫자 리스트 만들기
- 조건에 맞는 값만 남기기
- 문자열을 문자 단위로 쪼개기
- 입력값을 가공해서 바로 리스트 만들기
이런 데서는 그냥 반복문보다 더 자연스럽다.
🔗 주제
파이썬 리스트 컴프리헨션 정리
+ 마지막에 연습문제 첨부합니다 필요하면 사용하시면 되어요
개념 요약
리스트 컴프리헨션 기본형은 이거다.
[표현식 for 변수 in 반복가능한값]
조건까지 붙으면 이렇게 간다.
[표현식 for 변수 in 반복가능한값 if 조건]
if-else가 같이 들어가면 이렇게 된다.
[참일때값 if 조건 else 거짓일때값 for 변수 in 반복가능한값]
형태는 몇 개 안 되는데,
코테에서는 이걸 굉장히 자주 변형해서 쓰게 된다.
✅ 자주 쓰는 패턴
1) 기본 리스트 만들기
numbers = [i for i in range(10)]
print(numbers) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
가장 기본형이다.
반복문 돌면서 append() 하는 걸 한 줄로 줄인 형태다.
2) 값 변환하기
squares = [i * i for i in range(1, 11)]
print(squares) # [1, 4, 9, 16, ..., 100]
이건 코테에서 꽤 자주 나온다.
입력을 그대로 쓰지 않고, 어떤 규칙으로 가공할 때 많이 쓴다.
3) 조건 필터링하기
evens = [i for i in range(21) if i % 2 == 0]
print(evens) # [0, 2, 4, ..., 20]
조건에 맞는 값만 남긴다.
이건 반복문 + if문보다 훨씬 깔끔하게 보일 때가 많다.
4) if-else 같이 쓰기
labels = ["even" if i % 2 == 0 else "odd" for i in range(10)]
print(labels)
값 자체를 바꿔서 넣을 때 쓴다.
이건 문법이 처음엔 좀 어색한데,
형태만 익숙해지면 금방 읽힌다.
5) 문자열 순회하기
chars = [ch for ch in "hello"]
print(chars) # ['h', 'e', 'l', 'l', 'o']
리스트 컴프리헨션은 range()만 도는 게 아니다.
문자열도 바로 순회할 수 있다.
6) 리스트 안의 값 가공하기
lengths = [len(word) for word in ["apple", "banana", "kiwi"]]
print(lengths) # [5, 6, 4]
이런 식으로 리스트 안의 각 원소를 가공해서 새 리스트를 만들 수도 있다.
코딩테스트에서 왜 자주 쓰는가
이건 결국 입력 가공이랑 연결돼서 그렇다.
코테에서 많이 하는 작업이 이런 거다.
- 숫자 리스트 만들기
- 특정 조건만 남기기
- 문자열 쪼개기
- 2차원 배열 만들기
- 값 변환해서 바로 저장하기
즉, 리스트 컴프리헨션은
문법 그 자체보다 전처리 패턴에 더 가깝다.
예를 들어 이런 건 거의 전형적인 형태다.
nums = [int(x) for x in input().split()]
이건 사실 split + map으로도 가능하다.
nums = list(map(int, input().split()))
둘 다 맞는데,
리스트 컴프리헨션은 중간에 가공이 더 붙기 쉬워서 편할 때가 있다.
예를 들면:
nums = [int(x) * 2 for x in input().split()]
이건 map()보다 컴프리헨션 쪽이 읽기 더 편하다.
생각해야 하는 부분
리스트 컴프리헨션은 편하긴 한데,
무조건 짧게 쓰는 게 좋은 건 아니다.
그래서 실전에서는
어디까지 쓰면 좋은지를 같이 봐야 한다.
1. 반복 + 조건 + 간단한 변환까지가 제일 좋다
이 정도는 보통 괜찮다.
[x * x for x in range(10) if x % 2 == 0]
읽는 사람도 바로 이해할 수 있다.
즉,
- 반복
- 조건
- 간단한 계산
여기까지는 리스트 컴프리헨션이 잘 맞는다.
2. 너무 많은 조건을 한 줄에 몰아넣으면 오히려 안 좋다
예를 들어 이런 식으로 길어지면
result = [x * 2 if x % 2 == 0 else x + 1 for x in nums if x > 0 if x < 100]
문법적으로는 가능해도 읽는 사람 입장에서 확 피곤해진다.
이럴 땐 그냥 for문으로 빼는 게 낫다.
즉, 리스트 컴프리헨션은
짧아서 좋은 게 아니라, 짧아도 읽히면 좋은 것이다.
3. 2중 for도 가능하지만, 남용하면 바로 가독성 깨진다
예를 들면 이런 식이다.
pairs = [(i, j) for i in range(3) for j in range(2)]
print(pairs)
이것도 코테에서 나오긴 한다.
근데 중첩이 늘어나면 바로 복잡해진다.
그래서 2중 for까진 종종 쓰지만,
그 이상부터는 좀 조심하는 게 낫다.
예외처리 / 주의할 점
⚠️ 1. if와 if-else 위치를 자주 헷갈린다
이건 처음에 제일 많이 헷갈린다.
조건 필터링
[i for i in range(10) if i % 2 == 0]
값 바꾸기
["even" if i % 2 == 0 else "odd" for i in range(10)]
즉,
- if만 뒤에 붙으면 → 걸러내기
- if else가 앞에 오면 → 값 바꾸기
이 차이를 구분해야 한다.
⚠️ 2. map이 더 자연스러운 경우도 있다
예를 들면 입력 숫자 여러 개를 그대로 정수 리스트로 바꾸는 건
nums = list(map(int, input().split()))
이쪽이 더 전형적이다.
반면 중간에 가공이 붙으면
nums = [int(x) * 2 for x in input().split()]
이쪽이 더 자연스럽다.
즉, 리스트 컴프리헨션이 항상 정답은 아니고
상황 따라 더 읽기 좋은 쪽을 고르는 게 맞다.
⚠️ 3. 한 줄에 다 우겨 넣으려고 하면 오히려 더 느려진다
짧게 쓰는 맛이 있다 보니
괜히 다 한 줄에 넣고 싶어진다.
근데 코테에서는
본인이 다시 봐도 이해 안 되는 코드면 오히려 손해다.
특히 디버깅해야 할 때
너무 꼬인 컴프리헨션은 오히려 더 불편하다.
내 시행착오
이 부분은 나도 꽤 공감 갔던 부분이다.
1. 그냥 “for문 줄인 문법”이라고만 생각했다
처음에는 진짜 그렇게만 봤다.
- append 줄이기
- 코드 짧게 쓰기
근데 실제로는 그보다
입력을 변환하는 패턴으로 더 자주 쓰였다.
이걸 늦게 봤다.
2. range만 도는 줄 알았다
처음엔 리스트 컴프리헨션 하면
무조건 range()만 생각났다.
근데 실제로는
- 문자열
- 리스트
- split 결과
- map 결과
이런 것도 다 바로 순회할 수 있다.
이걸 알고 나니까 훨씬 자주 쓰이기 시작했다.
3. if와 if-else 문법이 자꾸 헷갈렸다
이건 진짜 처음에 많이 꼬인다.
- 뒤에 if 붙는 건 필터링
- 앞에 if else 오는 건 값 변경
이 차이만 익숙해져도 훨씬 덜 헷갈린다.
4. 너무 복잡하게 쓰면 오히려 더 안 읽힌다는 걸 나중에 알았다
짧다고 무조건 좋은 게 아니었다.
결국 코테에서는
내가 다시 읽고 바로 이해되는 코드가 더 중요했다.
그래서 지금은
리스트 컴프리헨션도 짧고 단순할 때만 쓰는 쪽이 더 낫다고 본다.
한 줄 정리
리스트 컴프리헨션은 for문을 줄이는 문법이 아니라,
반복 + 조건 + 간단한 변환을 한 번에 처리하는 코테용 패턴으로 보는 게 더 잘 남는다.
'Coding Test > Python & Algorithm' 카테고리의 다른 글
| 다익스트라 알고리즘 정리 | BFS와 차이, 우선순위 큐 구현까지 (0) | 2026.04.28 |
|---|---|
| DFS와 BFS 차이 정리 | 코딩테스트에서 문제에 맞게 고르는 기준 (0) | 2026.04.28 |
| 파이썬 split과 map 정리 | 코딩테스트 입력 처리에서 자주 쓰는 이유 (0) | 2026.04.22 |
| 파이썬 deque 정리 | BFS에서 리스트 대신 deque를 쓰는 이유 (0) | 2026.04.20 |
