Python 조건부 표현식, 줄 연속, 제너레이터 표현식
요약
Python의 한 줄 if-else(조건부 표현식), 중첩 삼항 결합 규칙, 백슬래시(\) 줄 연속, 제너레이터 표현식과 sum/any/all 활용까지. 정보처리기사 실기에 자주 등장하는 한 줄 표현식 문법을 정리합니다.
표현식 한 줄 문법 핵심 정리
| 개념 | 형식 | 예시 |
|---|---|---|
| 조건부 표현식 | 값1 if 조건 else 값2 | x if x > 0 else -x |
| 중첩 조건부 표현식 | A if B else C if D else E | 뒤쪽 if-else가 먼저 묶임 (오른쪽 결합) |
| 백슬래시 줄 연속 | 줄 끝에 \ | 한 줄을 다음 줄과 이어 씀 |
| 암시적 줄 연속 | (), [], {} 안 | 괄호 안에서는 \ 없이도 줄바꿈 가능 |
| 제너레이터 표현식 | (식 for 변수 in 반복) | (x * 2 for x in lst) |
| 조건부 제너레이터 | (식 for 변수 in 반복 if 조건) | (x for x in lst if x > 0) |
| sum/any/all과 결합 | sum(식 for 변수 in 반복) | sum(x for x in lst) |
조건부 표현식 (한 줄 if-else) 쌩기초
조건부 표현식(Conditional Expression) 은 if-else 문장을 한 줄짜리 식으로 줄여 쓰는 문법입니다. 다른 언어의 삼항 연산자1 조건 ? A : B와 같은 역할을 하지만, 파이썬에서는 if와 else 키워드를 그대로 사용합니다.
기본 형식
조건이 참이면 값1, 거짓이면 값2를 결과로 내놓습니다. 결과 값이 앞에, 조건이 가운데, 대체값이 뒤에 오는 점이 일반 if문과 다릅니다.
같은 동작을 일반 if-else문으로 풀어 쓰면 다음과 같습니다.
조건부 표현식은 변수에 대입할 값을 조건에 따라 정할 때, 또는 함수의 인자나 return 값으로 한 줄에 넣을 때 자주 쓰입니다.
식(expression)이지 문장(statement)이 아니다
조건부 표현식은 하나의 값으로 평가되는 식입니다. 그래서 print(...)의 인자, return 뒤, 리스트 안 같은 식이 들어갈 수 있는 모든 자리에 쓸 수 있습니다.
반대로 대입문(x = 1)이나 print() 호출 같은 문장(statement) 은 조건부 표현식 안에 넣을 수 없습니다.
중첩된 조건부 표현식과 결합 규칙 기초
조건부 표현식의 값1이나 값2 자리에 또 다른 조건부 표현식을 넣을 수 있습니다. 정보처리기사 실기에서 가장 헷갈리는 형태가 바로 이 중첩 형태입니다.
처음 보면 (A if B else C) if D else E처럼 앞쪽부터 묶이는 것 같지만, 실제로는 뒤쪽 if-else가 먼저 묶입니다. 즉 다음과 같이 해석됩니다.
이 결합 규칙을 오른쪽 결합(right-associative) 이라고 부릅니다. "B면 A, 아니면 (D면 C, 아니면 E)" 순서로 읽으면 됩니다.
분해해서 읽는 요령
복잡한 중첩 조건부 표현식을 만나면 뒤쪽 if-else부터 괄호를 쳐서 분해합니다.
이렇게 분해하면 "level이 홀수면 n.v, 짝수면 (n이 있으면 0 + sum(...), 없으면 0)" 구조라는 것이 명확하게 보입니다.
일반 if-else로 풀어 쓰기 비교
| 한 줄 표현식 | 풀어 쓴 형태 |
|---|---|
x if x > 0 else -x | if x > 0: x else: -x |
A if B else C if D else E | if B: A elif D: C else: E |
1 if a else 2 if b else 3 | if a: 1 elif b: 2 else: 3 |
중첩 조건부 표현식은 사실상 if-elif-else와 같은 동작을 한 줄로 표현한 것입니다.
백슬래시 줄 연속 (\) 기초
파이썬은 한 줄이 너무 길어질 때 여러 줄로 나누어 쓸 수 있는 두 가지 방법을 제공합니다.
명시적 줄 연속: 백슬래시 \
줄 끝에 백슬래시 한 개(\)를 쓰면 "이 줄과 다음 줄을 한 줄로 이어 쓰겠다"는 뜻이 됩니다.
위 코드는 파서 입장에서는 다음과 한 줄로 같습니다.
조건부 표현식이 길어질 때도 줄 연속을 자주 씁니다.
위 코드는 다음 한 줄과 같습니다.
암시적 줄 연속: 괄호 안
괄호(()), 대괄호([]), 중괄호({}) 안에서는 백슬래시 없이도 자유롭게 줄을 바꿀 수 있습니다. 이를 암시적 줄 연속(implicit line continuation) 이라고 합니다.
리스트나 함수 호출에서도 마찬가지입니다.
| 방법 | 사용 위치 | 예시 |
|---|---|---|
명시적 (\) | 괄호 밖 일반 식 | total = 1 + 2 + \ |
| 암시적 | (), [], {} 안 | total = (1 + 2 + |
대부분의 파이썬 코드는 괄호 안 암시적 줄 연속을 권장합니다. 하지만 시험 문제에서는 백슬래시 줄 연속이 종종 등장하므로, 두 방법 모두 알아두어야 합니다.
제너레이터 표현식 기초
제너레이터 표현식(generator expression) 은 리스트 컴프리헨션의 대괄호 []를 소괄호 ()로 바꾼 형태입니다.
제너레이터 표현식의 형식
리스트 컴프리헨션과 모양이 거의 같지만, 결과로 만들어지는 것이 리스트가 아니라 제너레이터 객체라는 점이 다릅니다.
리스트 컴프리헨션과의 차이
| 항목 | 리스트 컴프리헨션 [...] | 제너레이터 표현식 (...) |
|---|---|---|
| 결과 자료형 | list | generator |
| 메모리 사용 | 모든 결과를 한꺼번에 저장 | 꺼낼 때마다 하나씩 계산 |
| 직접 출력 | 값이 그대로 보임 | <generator object ...>로 보임 |
for문으로 순회 | 가능 (여러 번 가능) | 가능 (한 번 소비 후 끝) |
sum(), any(), all() 인자 | 가능 | 가능 (괄호 생략 가능) |
리스트는 결과 5개를 메모리에 한꺼번에 만들어 보관하지만, 제너레이터는 for문 등으로 하나씩 꺼낼 때마다 그때그때 계산해서 내어줍니다. 그래서 메모리를 적게 쓰고, 첫 번째 값이 빨리 필요한 상황에 유리합니다.
직접 순회해 보기
제너레이터 객체는 for문이나 next() 함수로 값을 꺼낼 수 있습니다.
sum, any, all과 함께 쓰기 심화
제너레이터 표현식이 가장 자주 쓰이는 곳은 sum(), any(), all() 같은 집계 함수의 인자입니다. 이런 함수들은 이터러블2을 받아 한 번씩 순회하면서 값을 모으는 동작을 하므로, 제너레이터와 잘 맞습니다.
sum과 결합
sum(이터러블)은 이터러블의 모든 값을 더해 결과를 돌려줍니다.
함수 호출의 괄호 안에 제너레이터 표현식이 들어갈 때는 제너레이터 표현식의 괄호를 생략할 수 있습니다. sum(x * 2 for x in nums)는 sum((x * 2 for x in nums))와 같습니다.
조건부 제너레이터 표현식
리스트 컴프리헨션과 마찬가지로, 제너레이터 표현식에도 if 조건을 붙여 원하는 값만 골라낼 수 있습니다.
이 표현식을 일반 for문으로 풀어 쓰면 다음과 같습니다.
재귀 함수와 결합한 시험 패턴
정보처리기사 실기에서는 재귀 함수와 제너레이터 표현식이 함께 등장하는 패턴이 출제된 적이 있습니다. 트리 구조의 자식 노드들을 모두 더할 때 다음과 같은 형태로 자주 쓰입니다.
이는 다음 일반 for문과 같습니다.
sum() 안에 제너레이터 표현식을 넣어 한 줄로 줄여 쓴 형태입니다. 한 줄짜리 식이지만 동작은 위 일반 for문과 똑같다는 점을 외워두면 시험에서 분해하기 쉽습니다.
any와 all
any()와 all()도 같은 패턴으로 쓸 수 있습니다.