[ python ] 02. 파이썬스러운(pythonic) 코드_(2)

박찬영·2024년 3월 20일

파이썬 클린 코드

목록 보기
5/19
post-thumbnail

02 파이썬스러운 코드(2)

컴프리헨션(Comprehension)과 할당 표현식

컴프리헨션을 사용하면 코드를 보다 간결하게 작성할 수 있고, 일반적으로 가독성도 높아지기 때문에 자주 사용하는 것을 확인할 수 잇다. 그렇지만, 수집한 데이터에 대해서 어떤 변환을 해야 하는 경우라면 오히려 코드가 더 복잡해질 수도 있다. 이런 경우에는 간단하게 for 루프를 사용하는 것이 더 나은 선택이다.

여러 연산이 아니라 단일 명령어로 데이터 구조를 생성하려면 컴프리헨션을 사용하는 것이 좋다. 예를 들어, 다음과 같이 어떤 숫자들에 대해서 단순 계산이 포함된 목록을 만들고 싶다면,

numbers = []
for i in range(10):
	numbers.append(run_calulation(i))

코드에서 다음과 같이 바로 리스트를 만들 수 있다.

numbers = [run_calulation(i) for i in range(10)]

이러한 형식으로 작성된 코드는 list.append()를 반복적으로 호출하는 대신 단일 파이썬 명령어를 호출하므로 일반적으로 더 나은 성능을 보인다.

추가적인 예시를 통해서 효과를 확인해보면 다음과 같다.

먼저 상황은 클라우드 컴퓨팅 환경에서 AWS의 리소스를 식별하는 고유번호 같은 문자열을 받아서 해당 리소스의 계정 정보를 반환하는 함수를 생각해보면 다음과 같이 단순하게 작성해볼 수 있다.

from typing import Iterable, Set
def collect_account_ids_from_arns(arns: Iterable[str]) -> Set[str]:
	""" arn:partition:service:region:account-id:resource-id 형태의 ARN들이 주어진 경우
    	고유한 계정 ID (account-id)를 찾아서 반환
    """
    collected_account_ids = set()
    for arn in arns:
    	matched = re.match(ARN_REGEX, arn)
        if matched is not None:
        	account_id = matched.groupdict()["account_id"]
            collected_account_ids.add(account_id)
    return collected_account_ids

이는 많은 코드 라인을 가지고 있지만, 비교적 간단한 작업을 하고 있는데, 컴프리헨션을 사용하면 더 적은 라인으로 동일한 기능을 수행하는 함수를 만들 수 있다.

def collect_account_ids_from_arns(arns):
	matched_arns = filter(None, (re.match(ARN_REGEX, arn) for arn in arns))
    return {m.groupdict()["account_id"] for m in matched_arns}
    

함수의 첫 번째 줄은 map과 filter를 적용하는 것과 비슷하다. 먼저 정규 표현식을 제공된 문자열에 적용하고 None이 아닌 것들만 남긴다.

이 함수는 처음 함수보다 유지 보수가 쉽지만 여전히 두 개의 문장이 필요하다. 파이썬 3.8부터 할당 표현식(assignment expression)이 도입되면서 다음과 같이 한 문장으로 다시 작성할 수 있다.

def collect_account_ids_from_arns(arns: Iterable[str]) -> Set[str]:
	return {
    	matched.groupdict()["account_id"]
        for arn in arns
        if (matched := re.match(ARN_REGEX, arn)) is not None
    }

컴프리헨션 안쪽 세 번째 줄에 있는 구문을 통해서 문자열에 정규식을 적용한 결과가 None이 아닌 것들만 matched 변수로 저장되고, matched 변수를 다른 부분에서 사용할 수 있다.

3번째 코드가 2번째보다 더 나은 코드인지는 논쟁의 여지가 있지만, 세 번째 코드가 두 번째 코드보다 표현력이 뛰어나다고 저자는 말한다. 그리고 확실한건 2번째 3번째 코드가 첫 번째 코드보다 더 나은 것은 확실하다.
간결한 코드가 항상 더 나은 코드를 의미하는 것은 아니라는 것을 명심하자.

컴프리헨션의 가독성을 생각해야 하며, 정말로 이해하기 쉬운 코드가 되는 것이 아니라면, 한 줄 코드를 만들기 위해 노력하지 않도록 유의하자

컴프리헨션과 마찬가지로 할당 표현식 사용하는 이유는 성능 때문이다. 어떤 변환 작업을 위해 호출하는 경우 필요 이상으로 호출되기를 원하지 않을 것이다.

컴프리헨션을 통해 코드를 보다 간결하게 작성하고 일반적으로 성능을 높일 수 있기 때문에 컴프리헨션 기법을 연습하는 것이 좋아보인다. 또한 리스트 컴프리헨션만 알고 있었지만, 범위가 더 크다는 것을 알게 됐다.

profile
안녕하세요 박찬영입니다.

0개의 댓글