참고자료
소개
:= 대입 연산자를 walrus operator라고 부른다. walrus는 바다코끼리를 뜻하는데 :=이 마치 바다코끼리의 눈과 엄니를 닮아서라고 한다. 정식 명칭은 assignment expression이다.
Gopher라면 익숙할 이 대입 연산자는 코드를 간결하게 만들어준다. 다만 Python 3.8에서 도입된 연산자이므로 사용 시 버전에 유의해야 한다.
# Without :=
match = pattern.search(data)
if match is not None:
print(f"matched pattern: {match}")
# With :=
if (match := pattern.search(data)) is not None:
print(f"matched pattern: {match}")
:=를 활용하면 다양한 곳에서 변수 대입이 가능해진다. 파이썬의 창시자인 Tim은 위와 같이 한 줄에서 많은 처리가 일어나는 '바쁜' 코드를 선호하지 않는다고 밝혔다. 하지만 아래 예시와 같은 경우, := 연산자가 일반 대입 연산보다 편리함을 인정했다.
# Old
while True:
d = x // a**(n-1)
if a <= d:
break
a = ((n-1)*a + d) // n
return a
# New
while a > (d := x // a**(n-1)):
a = ((n-1)*a + d) // n
return a
코드가 훨씬 간결해진 것을 볼 수 있다. 이처럼 :=는 코드의 가독성을 높여줄 수 있다.
대입문과의 차이
x = y = z = 0 # x, y, z: (0, 0, 0)
(z := (y := (x := 0))) # x, y, z: (0, 0, 0)
x = 1, 2 # x: (1, 2)
(x := 1, 2) # x: 1
loc = x, y
loc := (x, y)
info = name, phone, *rest
info := (name, phone, *rest)
일반적으로 대입에 사용되는 =과 동일하게 사용할 수는 없다. 특히 ( )를 이용한 범위, 우선순위 지정이 중요하다.
- 괄호 없이는 여러 값을 대입할 수 없다.
- 대입되는 우선순위가 다르다.
- packing, unpacking을 수행하기 위해서는 괄호로 대입 우선순위를 정해주어야 한다.
사용 예시
아래 예시들이 반드시 '좋은' 코드라는 것은 아니다. 상황에 따라, 사람에 따라 선호하는 코드가 다를 수 있다. 다만 := 연산자의 다양한 사용 방법을 보여주고자 작성하였다.
1. 형식이 다른 #Tag 찾기
lines = ["#aa", " #bb", " *cc", "#dd"]
# Old
only_tags = True
for line in lines:
tag = line.lstrip()
if not tag.startswith('#'):
print(f"`{tag}` is not a tag")
only_tags = False
break
if only_tags:
print("All lines are tags")
# New
if all((tag := line.lstrip()).startswith('#') for line in lines):
print("All lines are tags")
else:
print(f"`{tag}` is not a tag")
# Output: `*cc` is not a tag
for-if문 대신 all를 이용해 코드를 축약할 수 있다. 참고로 all은 iterable 객체가 조건을 모두 만족할 경우, True를 반환하는 함수이다.
2. 입력 끝까지 읽어오기
# Old
while True:
line = stdin.readline()
if line is None:
break
print(line)
# New
while line := stdin.readline():
print(line)
위에서도 봤듯 while True: if ~ break 형식의 조건 반복문을 훨씬 간결하게 작성할 수 있다.
3. 제곱 값 계산하기
# Old
ys = [(f(x), f(x)**2, f(x)**3) for x in inputs]
# New
ys = [(y := f(x), y**2, y**3) for x in inputs]
위 #Old의 경우 f(x)를 (하나의 x에 대해) 3번 실행하게 된다. 반면 :=를 활용하면 한 번의 실행으로 연산에 사용되는 비용을 줄일 수 있다.