파이썬265번7 MIN
왈러스 연산자 vs 일반 대입
Python 3.8에 들어온 := 연산자는 표현식 안에서 대입을 합니다. 일반 대입과 무엇이 다른지, 어디서 코드를 간결하게 만들고 어디서 오히려 해치는지 정리합니다.
이 글은 PALDYN Tech Blog의 글입니다.원문 보기
지난 글에서 복사의 함정을 정리했다면, 이번 글은 비교적 가벼운 주제 하나를 다룬다. Python 3.8에서 들어온 왈러스 연산자(walrus operator) :=다. 생긴 모양이 바다코끼리(walrus)의 눈과 엄니를 닮았다고 해서 붙은 별명이고, 정식 명칭은 할당 표현식(assignment expression)이다. 이 작은 연산자 하나가 일반 대입 =과 어떻게 다른지, 그리고 언제 쓰는 게 좋고 언제 자제하는 게 좋은지 살펴본다.
대입을 표현식으로
핵심부터 말하면, 일반 대입 =은 문(statement)이고 왈러스 :=은 표현식(expression)이다. 문은 그 자체로 값을 갖지 않아서 다른 표현식의 일부로 끼워 넣을 수 없다. 그래서 다음은 문법 오류다.
if (n = len(data)) > 10: # SyntaxError — = 는 표현식이 아니다
...
반면 왈러스는 "이름에 값을 대입하면서, 그 값을 표현식의 결과로도 내놓는다." 덕분에 if나 while의 조건 안에서 대입과 검사를 한 번에 할 수 있다.
if (n := len(data)) > 10: # n에 길이를 담으면서 동시에 10과 비교
print(f"{n}개는 너무 많습니다")
여기서 n은 대입되고, 그 값(len(data))이 곧바로 > 10 비교에 쓰인다. 대입과 사용을 한 자리에 모은 것이 왈러스의 전부다.
가장 잘 어울리는 자리 — while 루프
왈러스가 가장 빛나는 곳은 "값을 읽어서, 그 값이 어떤 조건이면 계속하는" 반복문이다. 왈러스가 없던 시절에는 같은 읽기 코드를 루프 앞과 루프 끝에 두 번 적어야 했다.
# 왈러스 없이 — readline()을 두 번 적는다
line = f.readline()
while line:
process(line)
line = f.readline()
# 왈러스로 — 대입과 조건을 한 줄에
while (line := f.readline()):
process(line)
읽는 코드가 한 곳으로 모이면서 중복이 사라지고, "읽은 게 있는 동안 처리한다"는 의도가 한 줄에 또렷해진다. 이처럼 읽기·계산과 그 결과의 검사가 짝을 이루는 패턴이 왈러스의 가장 자연스러운 용도다.
컴프리헨션에서 계산 재사용
또 다른 좋은 자리는 컴프리헨션이다. 같은 계산을 조건과 결과 양쪽에서 써야 할 때, 왈러스가 없으면 그 비싼 계산을 두 번 적게 된다.
# 왈러스 없이 — f(x)를 두 번 호출한다
result = [f(x) for x in data if f(x) is not None]
# 왈러스로 — 한 번만 계산해서 재사용
result = [y for x in data if (y := f(x)) is not None]
아래쪽은 f(x)를 단 한 번 호출해 y에 담고, 그 y를 조건 검사와 결과 양쪽에서 함께 쓴다. 계산이 무겁거나 부작용이 있는 함수일수록 이 중복 제거의 가치가 크다.
자제해야 할 때
좋은 도구도 남용하면 독이 된다. 왈러스가 코드를 오히려 읽기 어렵게 만드는 경우들이 있다.
가장 흔한 오용은 그냥 한 줄짜리 평범한 대입을 굳이 왈러스로 바꾸는 것이다. 표현식 안에 끼워 넣을 이유가 없는데 :=을 쓰면 괄호만 늘고 가독성은 떨어진다.
# 나쁨 — 그냥 대입이면 되는데 표현식으로 위장
print(total := a + b)
# 좋음 — 의도가 분명한 평범한 대입
total = a + b
print(total)
또 하나는 한 표현식에 왈러스를 여러 개 욱여넣거나, 함수 인자 한가운데서 깜짝 대입을 하는 것이다. 읽는 사람이 "여기서 변수가 언제 어떤 값으로 생겼지?"를 추적하게 만들면, 간결함을 얻은 대가로 명확함을 잃는다.
판단 기준은 예전 글에서 본 그 한 줄로 돌아간다 — "읽기 쉬움이 우선한다." 왈러스가 중복을 없애고 의도를 또렷하게 하면 좋은 사용이고, 단지 줄 수를 줄이려고 흐름을 숨기면 나쁜 사용이다.
정리
왈러스 연산자 :=은 일반 대입 =과 달리 표현식이어서, 값을 대입하면서 동시에 그 값을 조건 검사나 다른 계산에 쓸 수 있다. while (line := f.readline()):처럼 읽기와 검사가 짝을 이루는 반복문, 그리고 컴프리헨션에서 무거운 계산을 한 번만 하고 재사용하는 경우에 특히 잘 어울린다. 반대로 평범한 대입을 굳이 표현식으로 위장하거나 한 식에 여러 번 끼워 넣어 흐름을 숨기는 것은 피해야 한다. 변수의 범위를 좁게 유지하면서 중복을 없애는 도구로 쓸 때, 왈러스는 코드를 더 파이썬답게 만든다.
언어의 본질과 설치에서 시작해 자료형과 제어문, 함수와 클래스, 모듈과 패키지, 파일과 예외, 이터레이터와 제너레이터, 동시성과 타입 힌트, 패키징과 테스트, 그리고 실무 라이브러리와 보안·함정까지 — 파이썬을 다루는 데 필요한 지형을 한 바퀴 돌았다. 각 주제의 공통된 교훈은 하나였다. "파이썬이 무엇을, 언제, 어떻게 처리하는가"를 정확히 이해하면, 대부분의 혼란은 예측 가능한 동작으로 바뀐다는 것이다. 그동안 함께해 주셔서 감사하다.
지난 글: 얕은 복사 vs 깊은 복사
읽어주셔서 감사합니다. 😊

