채용을 위한 코딩테스트는 점수만 보지 않는 대신, 제출한 코드의 품질을 평가할 수 있기 때문에 코좋은 코딩 스타일로 작성해야 한다.
def num_matching_subseq(self, s: str, words: List[str]) -> int:
matched_count = 0
for word in words:
pos = 0
for i in range(len(word)):
found_pos = s[pos:].find(word[i])
if found_pos < 0:
matched_cound -= 1
break
else:
pos += found_pos + 1
matched_count += 1
return matched_count
리스트 컴프리헨션은 대부분 한 줄로 적게 되는 경우가 많은데 가능한 대로 다음과 같이 역할별로 줄 구분을 하면 훨씬 더 가독성이 높아지고 이해하기 쉬워진다.
str1s = [
str1[i:i+2].lower() for i in range(len(str1) - 1)
if re.findall('[a-z]{2}', str1[i:i + 2].lower())
]
차라리 이처럼 모두 풀어서 쓰는 것도 가독성을 위해서라면 나쁘지 않다.
str1s = []
for i in range(len(str1) - 1):
if re.findall('[a-z]{2}', str1[i:i + 2].lower()):
str1s.append(str1[i:i + 2].lower())
리스트 컴프리헨션은 대체로 표현식이 2개를 넘지 않아야 한다. 다음과 같이 여러 표현식을 여러 줄에 걸쳐 표현하면 가독성이 지나치게 떨어진다.
return [(x, y, z)
for x in range(5)
for y in range(5)
if x != y
for z in range(5)
if y != z]
함수의 기본 값으로 가변 객체를 사용하지 않아야 한다.
함수가 객체를 수정하면(리스트에 아이템을 추가한다든지 등) 기본 값이 변경되기 때문에 다음과 같이 기본값으로 []나 {}를 사용하는 것은 지양해야 한다.
대신 다음과 같이 불변 객체를 사용한다. None을 명시적으로 할당하는 것도 좋은 방법이다.
No : def foo(a, b = []):
...
No : def foo(a, b: Mapping = {}):
...
Yes : def foo(a, b = None):
if b is None:
b = []
...
Yes : def foo(a, b: Optional[Sequence] = None):
if b is None:
b = []
Yes: if not users:
print('no users')
if foo == 0:
self.handle_zero()
if i % 10 == 0:
self.handle_multiple_of_ten()
No: if len(users) == 0:
print('no users')
if foo is not None and not foo:
self.handle_zero()
if not i % 10:
self.handle_multiple_of_ten()