Language/Python
[Effective Python] Better way 10. 대입식을 사용해 반복을 피하라
dashwood
2022. 8. 23. 21:56
Better way 10. 대입식을 사용해 반복을 피하라
fresh_fruit = {
'apple': 10,
'banana': 8,
'lemon': 5,
}
def make_lemonade(count):
print(f'Making {count} lemons into lemonade')
def out_of_stock():
print('Out of stock!')
count = fresh_fruit.get('lemon', 0)
if count:
make_lemonade(count)
else:
out_of_stock()
위 코드에서 count 변수는 if 문의 첫 번째 블록 안에서만 쓰인다. if 앞에서 count를 정의하면 else 블록이나 그 이후의 코드에서 count 변수에 접근해야 할 필요가 있는 것 처럼 보이기 때문에 실제보다 변수가 중요해 보인다.
대입 연산자는 우선 count 변수에 값을 대입하고, if 문의 맥락에서 대입된 값을 평가해 프로그램 흐름을 어떻게 제어할 지 판단한다. 이런 두 단계의 동작(대입 후 평가)이 왈러스 연산자의 핵심!
if count := fresh_fruit.get('레몬', 0):
make_lemonade(count)
else:
out_of_stock()
바나나 슬라이스가 최소 두 개는 필요하고, 슬라이스가 부족하면 OutOfBananas 예외를 발생시켜야 한다면 다음과 같이 작성할 수 있다.
pieces = 0
if (count := fresh_fruit.get('바나나', 0)) >= 2:
pieces = slice_bananas(count)
else:
pieces = 0
try:
smoothies = make_smoothies(pieces)
except OutOfBanans:
out_of_stock()
파이썬에서 switch/case 문이나 do/while 루프를 쓸 수 없지만, 대입식을 사용하면 이런 기능을 깔끔하게 흉내낼 수 있다.
count = fresh_fruit.get('banana', 0)
if count >= 2:
pieces = slice_bananas(count)
to_enjoy = make_smoothies(pieces)
else:
count = fresh_fruit.get('apple', 0)
if count >= 4:
to_enjoy = make_cider(count)
else:
count = fresh_fruit.get('lemon', 0)
if count:
to_enjoy = make_lemonade(count)
else:
to_enjoy = 'Nothing'
# switch/case 처럼 왈러스문을 사용하는 예
if (count := fresh_fruit.get('banana', 0)) >= 2:
pieces = slice_bananas(count)
to_enjoy = make_smoothies(pieces)
elif (count := fresh_fruit.get('apple', 0)) >= 4:
to_enjoy = make_cider(count)
elif count := fresh_fruit.get('lemon', 0):
to_enjoy = make_lemonade(count)
else:
to_enjoy = 'Nothing'
FRUIT_TO_PICK = [
{'apple': 1, 'banana': 3},
{'lemon': 2, 'lime': 5},
{'orange': 3, 'melon': 2},
]
def pick_fruit():
if FRUIT_TO_PICK:
return FRUIT_TO_PICK.pop(0)
else:
return []
def make_juice(fruit, count):
return [(fruit, count)]
bottles = []
while True: # 무한 루프
fresh_fruit = pick_fruit()
if not fresh_fruit: # 중간에서 끝내기
break
for fruit, count in fresh_fruit.items():
batch = make_juice(fruit, count)
bottles.extend(batch)
# 왈러스를 사용하는 예
bottles = []
while fresh_fruit := pick_fruit():
for fruit, count in fresh_fruit.items():
batch = make_juice(fruit, count)
bottles.extend(batch)