효율적인 쇼트 서킷 로직을 사용하려면 any나 all에게 이터레이터를 전달할 것

Tasker_Jang·2026년 8월 14일
post-thumbnail

🤔 이게 왜 문제인가

십만 줄짜리 로그 파일을 훑으면서 "손상된 줄이 하나라도 있는가"를 판단하는 코드를 상상해 보시기 바랍니다. 두 번째 줄에서 이미 손상이 발견됐다면 나머지 구만 구천여 줄은 읽을 이유가 없습니다. any와 all은 정확히 그런 판단을 위해 만들어진 내장 함수입니다. all은 거짓인 원소를 만나는 순간, any는 참인 원소를 만나는 순간 즉시 멈춥니다.

문제는 우리가 무심코 찍는 대괄호 한 쌍입니다. all([...])처럼 리스트 컴프리헨션(list comprehension)을 넘기면, all이 호출되기도 전에 파이썬이 모든 원소를 평가해 리스트를 완성합니다. 쇼트 서킷이 작동할 기회 자체가 사라지는 셈입니다. 검사 함수가 단순 비교라면 체감이 없지만, 그 안에 파일 파싱이나 네트워크 호출이 섞여 있다면 이야기가 완전히 달라집니다.

💣 흔한 실수

def is_valid(row):
    print(f'검사 수행: {row!r}')  # 실제 호출 횟수를 눈으로 확인합니다
    return row.strip() != ''


rows = ['alpha', '', 'beta', 'gamma']

# 대괄호 때문에 all이 실행되기 전에 리스트가 먼저 완성됩니다
result = all([is_valid(row) for row in rows])

print(result)  # False — 하지만 검사는 이미 4번 모두 끝났습니다

두 번째 원소에서 결론이 났는데도 is_valid가 네 번 호출됩니다. 리스트 컴프리헨션은 전체를 메모리에 올린 뒤 그 완성품을 all에게 건네기 때문입니다. 원소가 백만 개라면 불필요한 연산과 메모리를 그대로 떠안게 됩니다.

✅ 파이썬다운 방법

rows = ['alpha', '', 'beta', 'gamma']

# 대괄호를 빼면 제너레이터 표현식(generator expression)이 됩니다
result = all(is_valid(row) for row in rows)

print(result)  # False — 검사는 2번만 수행되었습니다

# 반대 방향 질문은 any로 표현하는 편이 읽기 편합니다
has_broken = any(not is_valid(row) for row in rows)

print(has_broken)  # True — 역시 2번에서 멈춥니다

바뀐 것은 대괄호를 뺀 것뿐이지만, 이제 all은 원소를 하나씩 당겨 쓰다가 거짓을 만나면 그 자리에서 반환합니다. 남은 제너레이터(generator)의 이터레이터 참조는 버려지고 가비지 컬렉션되므로 끝까지 순회되지 않습니다. 불필요한 연산과 메모리를 동시에 아끼는, 성능 측면의 개선입니다. any와 all 중 무엇을 쓸지는 조건을 긍정형으로 쓰는 쪽이 덜 헷갈리는지를 기준으로 고르는 것이 좋습니다.

📎 기억할 것

  • all은 거짓인 원소를, any는 참인 원소를 만나는 즉시 순회를 중단합니다.
  • 쇼트 서킷으로 중단된 뒤 남은 이터레이터는 끝까지 소비되지 않고 가비지 컬렉션됩니다.
  • 리스트 컴프리헨션을 넘기면 모든 원소가 미리 평가되어 쇼트 서킷 이점이 사라집니다.
  • 인자가 하나뿐일 때는 대괄호만 빼면 곧바로 제너레이터 표현식이 됩니다.
  • 검사 조건을 긍정형으로 표현할 수 있는 쪽을 골라 any와 all 중 하나를 선택합니다.

🛠 실무에서 어디 쓸까

FastAPI의 권한 검사 의존성이 좋은 예입니다. if any(role in user.roles for role in required_roles): 형태로 작성하면 일치하는 역할을 찾는 즉시 나머지 비교를 건너뜁니다. 권한 조회가 캐시 미스로 외부 저장소를 때리는 구조라면 절감 효과가 그대로 응답 시간으로 돌아옵니다.

데이터 파이프라인의 사전 검증 단계에서도 유용합니다. 업로드된 CSV를 처리하기 전에 all(has_required_columns(chunk) for chunk in read_chunks(path))로 확인하면, 첫 청크에서 스키마가 어긋나는 순간 파일 전체를 읽지 않고 빠르게 실패할 수 있습니다.

profile
ML Engineer 🧠 | AI 모델 개발과 최적화 경험을 기록하며 성장하는 개발자 🚀 The light that burns twice as bright burns half as long ✨

0개의 댓글