itertools.chain 객체와 lazy iterator

송용진·2025년 6월 5일

Python / Django

목록 보기
3/23

itertools.chain 객체와 lazy iterator는
데이터 처리와 관련하여 중요하며,
효율적인 코드를 작성하는 데 도움이 됨

itertools.chain 객체

itertools는 파이썬 표준 라이브러리로,
효율적인 반복을 위한 함수들을 제공
그중 itertools.chain()은 여러 개의 순회 가능한(iterable) 객체
(예: 리스트, 튜플, Django QuerySet 등)를 하나로 연결하여
새로운 iterator를 만드는 함수

Django에서 여러 QuerySet의 결과를 하나로 합쳐서 사용하고 싶을 때
itertools.chain()을 유용하게 사용할 수 있음
예를 들어, 서로 다른 조건으로 필터링된 두 개의 QuerySet을 합쳐서 하나의 목록처럼 다루고 싶을 때 사용

from itertools import chain
from .models import MyModel

queryset1 = MyModel.objects.filter(status='active')
queryset2 = MyModel.objects.filter(is_featured=True)

combined_results = chain(queryset1, queryset2)

# combined_results는 이제 MyModel 객체들을 순회하는 하나의 iterator
for item in combined_results:
    print(item.name)

itertools.chain의 장점은 데이터를 바로 메모리에 로드하여
새로운 리스트를 만들지 않고,
요청 시에 데이터를 하나씩 가져온다는 것
특히 다루는 데이터의 양이 많을 때
메모리 효율성을 높이는 데 도움이 됨

하지만 여기서 주의할 점은
itertools.chain()의 결과는 Django의 QuerySet 객체가 아님

단순히 여러 순회 가능한 객체의 요소들을 순서대로 제공하는 iterator일 뿐임
따라서 combined_results 객체에 .filter(), .order_by(), .annotate()와 같은 QuerySet 전용 메서드를 직접 사용할 수 없음

QuerySet 메서드를 사용하려면
chain으로 연결하기 전에 각 QuerySet에 미리 적용하거나,
chain으로 얻은 iterator를 리스트 등으로 변환한 후
파이썬의 기본 리스트/iterator 처리 방법을 사용해야함

Lazy Iterator

"Lazy Evaluation"는
연산의 결과 값이 필요할 때까지 계산을 미루는 방식

"Lazy Iterator"는 이러한 지연 평가 방식을 사용하는 iterator를 말함

Django의 QuerySet은 대표적인 Lazy Evaluation의 예시임
MyModel.objects.filter(status='active').order_by('name')
와 같이 QuerySet을 정의하더라도,
이 시점에는 실제로 데이터베이스 쿼리가 실행되지 않음

# 이 시점에는 데이터베이스 쿼리가 실행되지 않음
active_users = User.objects.filter(is_active=True)
print("QuerySet이 정의되었음")

# 데이터를 순회하거나, 리스트로 변환하거나, 특정 메서드(len(), count() 등)를 호출할 때 쿼리가 실행됨
for user in active_users: # 이 순간 데이터베이스 쿼리가 실행됨
    print(user.username)

print("데이터 순회가 끝났음")

QuerySet이 지연 실행되는 이유

효율성

필요한 데이터만 그때그때 가져오므로
메모리를 효율적으로 사용할 수 있음
모든 데이터를 미리 메모리에 로드할 필요가 없음

유연성

여러 .filter(), .exclude(), .order_by() 등을 연결하여 복잡한 쿼리를 구성할 수 있음
Django ORM은
마지막에 최종적으로 필요한 데이터만 가져오기 위한
하나의 효율적인 SQL 쿼리를 생성하여 실행함

itertools.chain 역시
여러 순회 가능한 객체를 합쳐 하나의 iterator를 반환하며,
이 iterator 또한 Lazy하게 작동함
즉, chain으로 연결된 객체들을 순회할 때
실제로 데이터가 필요할 때
각 객체로부터 값을 가져오는 방식임

요약

Django QuerySet은 데이터베이스와의 상호작용을 Lazy하게 처리하여 효율성을 높이는 객체이며,
itertools.chain은 파이썬의 일반적인 Lazy Iterator로
여러 순회 가능한 객체를 하나처럼 다룰 수 있게 해주는 도구itertools.chain은 Django QuerySet을 포함한 다양한 순회 가능한 객체와 함께 사용될 수 있지만,
chain 결과 자체는 QuerySet이 아니므로
QuerySet의 특별한 기능들은 사용할 수 없다는 점을 기억할 것

profile
개발자

0개의 댓글