1. Pythonic
๊ฐ. Helper Function > Complex Expressions
๋ณต์กํ ์ ๋ณด๋ค๋ ๋์ฐ๋ฏธ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋
์ฑ์ ๋์ผ ๊ฒ
Donโt Do This
request = {"name": ["MJ"], "phone": ["010-111"]}
name = request.get("name", [""])[0] or 0
Python
๋ณต์ฌ
Do this
def get_first_value(values, key, default=0):
found = values.get(key, [''])
if found[0]:
return int(found[0])
return default
request = {"name": ["MJ"], "phone": ["010-111"]}
name = get_first_value(request, "name")
Python
๋ณต์ฌ
Why
โข
๋ช
ํํจ์ ๋ฐ๋ฅธ ๊ฐ๋
์ฑ ์ฐ์๊ฐ ๊ฐ๊ฒฐํจ์ ๋ฐ๋ฅธ ๋ฏธ์ธํ ์ฑ๋ฅ ์ฐ์ ๋ณด๋ค ๋ซ๋ค
โ ๊ฐ๋
์ฑ ์ฐ์๋ ์ ์ง๋ณด์์ ํธ๋ฆฌํจ์ผ๋ก ์ด์ด์ง๊ณ ์ด๊ฒ์ ํด๋จผ์๋ฌ ๊ฐ์์ ์ ์ง๋ณด์ ์ฉ์ด๋ก ์ด์ด์ง
โ ๋ฏธ์ธํ ์ฑ๋ฅ ์ฐ์๋ ์ฌ๋์ด ์ฒด๊ฐํ ์ ์์
๋. unpacking > indexing
๋ฐ๋ณต๋ฌธ์์ index ๋์ unpacking์ ์ฌ์ฉํ์ฌ ๊ฐ๋
์ฑ์ ๋์ผ ๊ฒ
Donโt Do This
name_age_tuples = [('MJ', 30), ('DB', 29)]
for i in range(len(name_age_tuples)):
name_age_tuple = name_age_tuples[i]
name = name_age_tuple[0]
age = name_age_tuple[1]
print(f'{i + 1}: {name}, {age}')
Python
๋ณต์ฌ
Do this
โข
ํนํ ๋ฐ๋ณต๋ฌธ์์ unpacking ์ฌ์ฉ ์ ์ฝ๋์ ๊ฐ๋
์ฑ์ด ํฌ๊ฒ ํฅ์๋๋ค
name_age_tuples = [('MJ', 30), ('DB', 29)]
for i, (name, age) in enumerate(name_age_tuples, 1):
print(f'{i}: {name}, {age}')
Python
๋ณต์ฌ
Why
โข
์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด โ์๊ฐ์ ์ก์'์ด ์ค๊ธฐ ๋๋ฌธ์ ์ฝ๋์ ์๋๊ฐ ๋ช
ํํ๊ฒ ๋๋ฌ๋๋ค
๋ค. zip for iterators in parallel
๊ธธ์ด๊ฐ ๊ฐ์ ๋ณต์๊ฐ์ ์ดํฐ๋ ์ดํฐ ์ฌ์ฉ ์ zip์ ์ฌ์ฉํ์ฌ ๊ฐ๋
์ฑ์ ๋์ผ ๊ฒ
Donโt Do This
longest_name = None
max_count = 0
for i in rage(len(names)):
count = counts[i]
if count > max_count:
longest_name = names[i]
max_count = count
Python
๋ณต์ฌ
Do this
โข
๊ธธ์ด๊ฐ ๋ค๋ฅผ ๊ฒฝ์ฐ, ์งง์ ๊ธธ์ด์ ์ดํฐ๋ ์ดํฐ์ ๋ง์ถฐ ๋ฐ๋ณต๋จ
โ ๊ธด ๊ธธ์ด์ ์ดํฐ๋ ์ดํฐ์ ๋ง์ถฐ ๋ฐ๋ณตํ ๋๋ zip ๋์ itertools.zip_longest ํจ์ ์ฌ์ฉ
โ ์ด ๋, ์งง์ ๊ธธ์ด์ ์ดํฐ๋ ์ดํฐ์ outbound ์์๋ None ์ฒ๋ฆฌ๋จ
for count, name zip(counts, names):
if count > max_count:
longest_name = name
max_count = count
Python
๋ณต์ฌ
Why
โข
์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด โ์๊ฐ์ ์ก์'์ด ์ค๊ธฐ ๋๋ฌธ์ ์ฝ๋์ ์๋๊ฐ ๋ช
ํํ๊ฒ ๋๋ฌ๋๋ค
๋ผ. assignment expression
์๋ฌ์ค ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ฉ์๋ ํธ์ถ๊ณผ ๋ณ์ ํ ๋น ์์ ๋ฐ๋ณต์ ์ค์ผ ๊ฒ
Donโt Do This
Python
๋ณต์ฌ
Do this
Python
๋ณต์ฌ
Why
โข
2. List & Dict
๊ฐ. unpacking > slicing
source interator ๋ฐ๋ณต ์ฌ์ฉ ์ unpakcing ํ์ฉํ์ฌ ์ฝ๋๋ฐ๋ณต๊ณผ ํด๋จผ์๋ฌ ๊ฐ๋ฅ์ฑ์ ์ค์ผ ๊ฒ
Donโt Do This
all_csv_rows = list(generate_csv(source))
header = all_csv_rows[0]
rows = all_csv_rows[1:]
print(f'header: {header}, len of rows: {len(rows)}')
Python
๋ณต์ฌ
Do this
โข
๋จ, unpacking์ ๋ฐ๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ถฉ๋ถํ ๊ฐ๋นํ ์ ์๋ ๊ฒฝ์ฐ๋ง ์ฌ์ฉํ๋ค
โ ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ์ ๋ฐ๋ฅธ ํ๋ก๊ทธ๋จ ๊ฐ์ ์ข
๋ฃ๋ก ์ด์ด์ง ์ ์์
โข
๋ง์ฝ rows์ ๋ง์ ๋ฐ์ดํฐ๊ฐ ๋ค์ด์์ ๊ฐ๋ฅ์ฑ์ด ์๋ค๋ฉด ์์ธ๋ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ํตํด ๊ฐ๋ฅ์ฑ์ ์ฌ์ ์ฐจ๋จํด์ผ ํ๋ค
โ ์๋ฅผ ๋ค์ด csvํ์ผ ์ฌ๋ถ ๋ฐ ํ์ผ ์ด๋ฆ ๋ฑ์ ์ฒดํฌํ์ฌ ์๋ํ csv ํ์ผ๋ง ๋ฐ์ ์ ์๋๋ก ์ ํจ์ฑ ๋ก์ง์ ์ถ๊ฐํ๋ค
it = generate_csv(source)
header, *rows = it
print(f'header: {header}, len of rows: {len(rows)}')
Python
๋ณต์ฌ
Why
โข
unpacking ์ฌ์ฉ ์ index์ ๊ธฐ๋ฐํ slicing ์ฌ์ฉ ๋ณด๋ค ํด๋จผ์๋ฌ๋ฅผ ์ค์ด๋๋ฐ ์ฉ์ดํ๋ค
โข
unpacking ์ฌ์ฉ์ ๋ฐ๋ผ ๋ฐ๋ณต์ ์ค์ด๊ณ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ง ์์์ผ๋ก์จ ์ฝ๋์ ์๋๊ฐ ๋ช
ํํ๊ฒ ๋๋ฌ๋๋ค
๋. get > in, KeyError
Donโt Do This
Python
๋ณต์ฌ
Do this
Python
๋ณต์ฌ
Why
โข
๋ค. defaultdict > setdefault
Donโt Do This
Python
๋ณต์ฌ
Do this
Python
๋ณต์ฌ
Why
โข
๋ผ. __missing__ for setting default
Donโt Do This
Python
๋ณต์ฌ
Do this
Python
๋ณต์ฌ
Why
โข
3. Function
๊ฐ. Exception > None
์์ธ ๋ฐ์ ์ None์ ๋ฐํํ์ง ๋ง๊ณ Exception์ ๋ฐ์์์ผ ํด๋จผ์๋ฌ๋ฅผ ์ค์ผ ๊ฒ
Donโt Do This
โข
unpacking์ ๋ฐ๋ฅธ None ๋ฐํ๋ ์์
def divide(a, b):
try:
return a / b
except ZeroDivisionError:
return None
Python
๋ณต์ฌ
def divide(a, b):
try:
return True, a / b
except ZeroDivisionError:
return False, None
Python
๋ณต์ฌ
Do this
โข
Exception ์ฒ๋ฆฌ ๋ถ๋ถ์ด ์๋ค๋ฉด ์๋์ ๊ฐ์ด docstring ์์ฑํ์ฌ ๊ด๋ จ ์ค๋ช
์ ์ถ๊ฐํ๋ ๊ฒ์ ๊ถ์ฅ
โข
๋ช
์์ฑ ํฅ์์ ์ํด ํ์
์ง์ ๊ถ์ฅ
def divide(a: float, b: float) -> float:
"""a๋ฅผ b๋ก ๋๋
Raises:
ValueError: b๊ฐ 0์ผ ๋ ๋๋์
์ ํ ์ ์๋ค
"""
try:
return a / b
except ZeroDivisionError:
return ValueError('์๋ชป๋ ์
๋ ฅ')
try:
result = divide(x, y)
except ValueError:
print('์๋ชป๋ ์
๋ ฅ')
else:
print(f'๊ฒฐ๊ณผ: {result}')
Python
๋ณต์ฌ
Why
โข
ํจ์์์ None ๋ฐํ ์ โ0 ๋๋ Falseโ ๋ฐํ์ ๋ฐ๋ฅธ ๊ฐ ์ฒ๋ฆฌ์ ํผ๋๋ ์ ์๋ค
โ ์กฐ๊ฑด๋ฌธ์์ None๊ณผ 0์ False๋ ๋ชจ๋ False๋ก ํ๊ฐ๋๋ค
โข
โNone ๋ฐํโ์ โ์์ธ ๋ฐ์โ๊ณผ ๋
ผ๋ฆฌ์ ์ฐ๊ด์ฑ์ด ๋จ์ด์ง๋ค
โ None์ โ๊ฐ์ด ์ง์ ๋์ง ์์'์ ๋ปํ๋ฏ๋ก ๋
ผ๋ฆฌ์ ์ผ๋ก โ์์ธ ๋ฐ์'๊ณผ ์ง์ ์ ์ธ ์ฐ๊ด์ด ์๋ค
Reference
โข
Brett Slatkin, Effective Python 2nd Edition, https://effectivepython.com/
โข
(๋ฒ์ญ๋ช
) ํ์ด์ฌ ์ฝ๋ฉ์ ๊ธฐ์ , https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=254321728