[Python] iter()와 next()

Suhyeon Lee·2025년 8월 10일

파이썬 별찍기 응용 연습하다가 궁금해져서 내용 정리

numbers = iter(range(1, 11))
lines = []
for i in range(1, 5):
    line = "  " * (4 - i)
    line += " ".join(str(next(numbers)) for _ in range(i))
    lines.append(line)
print("\n".join(lines))
  • numbers = iter(range(1, 11))는 이터레이터(iterator) 객체를 만듦
    • 이터레이터는 값을 하나씩 "꺼내쓰는" 역할
    • next(numbers)를 할 때마다 다음 숫자를 하나씩 반환
  • [i for i in range(1, 11)]와의 차이점
    • [i for i in range(1, 11)]
      • 리스트(모든 값 저장)
      • 이미 값이 모두 만들어져 있어서 반복문에서 여러 번 사용 가능함(재사용 가능)
    • iter(range(1, 11))
      • 이터레이터(한 번에 한 값씩 꺼냄, 일회성)
      • next(numbers)로 값을 소모하며 사용
      • 반복문 등에서 한 번만 모든 값을 순서대로 사용할 때 적합
      • 다 소모하면 다시 쓸 수 없음(재사용 불가, 다시 만들 필요 있음)
  • next(numbers)로 값을 계속 꺼내쓰는 코드가 등장할 때 이터레이터를 써야 원하는 대로 각 줄에 쓸 숫자를 한 번씩 꺼낼 수 있음!

만약 [i for i in range(1,11)]을 대신 사용하게 되면, 이 리스트에서 반복적으로 값을 꺼내 바로바로 "소모"하는 방식이 아니므로 next()로 값을 하나씩 꺼내는 코드는 작동하지 않음
(리스트는 next로 소모하지 않음, 인덱스로 접근해야 함)

  • 정리
    • iter는 "순차적으로 하나씩 꺼내주는 객체(이터레이터)를 만들어주는 함수"
    • 한 번에 모두 담아두고 여러 번 쓸 때는 리스트
    • 순서대로 한 번씩 꺼내서 자동으로 진행하고 싶을 때는 이터레이터

iter() 함수

  • 반복 가능한 객체를 이터레이터(iterator) 객체로 변환하는 역할
  • 기본 원리
    • Iterable(반복 가능한 객체)
      • 리스트, 튜플, 문자열, 딕셔너리 등 반복(for문 등)이 가능한 모든 객체
    • Iterator(이터레이터)
      • next()로 값을 하나씩 꺼낼 수 있는 객체
  • 리스트 자체는 반복은 되지만 이터레이터가 아니고, iter()를 사용해야만 이터레이터가 생성됨
a = [1, 2, 3]
it = iter(a)
print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # 3
# 다음 값을 꺼내면 StopIteration 예외 발생
  • 이터레이터는 이미 다 꺼낸 값은 다시 사용할 수 없고, 다시 쓰려면 새로 만들어야 함
  • iter() 함수의 두 가지 주요 사용법
    1. iter(반복가능한객체)
      • 리스트, 튜플 등 반복 가능한 객체를 이터레이터로 변환
    2. iter(호출가능한객체, 종료값)
      • 매개변수 없는 함수를 첫 인자로, 반복을 끝낼 감시값(sentinel)을 두 번째 인자로 넣어줌
      • 예: 무작위 값을 반복적으로 받다가 특정 값이 나오면 반복 종료
import random
it = iter(lambda: random.randint(0, 5), 2)
for v in it:
    print(v)    # 2가 나올 때까지 계속 출력
  • 정리
    • iter()는 반복 가능한 객체를 이터레이터 객체로 변환하는 함수
    • 이터레이터는 next()로 값을 하나씩 꺼냄
    • 이터레이터에서 값을 모두 꺼내면 StopIteration 예외 발생
    • 한 번 소진된 이터레이터는 다시 사용할 수 없음
      • 다시 쓰고 싶으면 새로 만들어야 함
    • iter(fn, 종료값)처럼 호출 가능한 객체를 감시값(sentinel)과 함께 사용 가능
    • 이터레이터를 사용하면 메모리 효율적 처리 및 지연 평가가 가능
    • 이터레이터와 관련된 동작들은 모두 파이썬의 for문, list comprehensions, 제너레이터 등 반복 구조의 근간이 됨
  • 함수 호출 시 내부적으로 거치는 과정:
    1. 객체가 __iter__() 메서드를 구현했는지 확인
      • iter(obj) 호출 → 해당 객체 obj가 __iter__()라는 메서드를 가지고 있는지 파이썬이 검사함
      • 만약 obj가 __iter__()를 구현하고 있다면, __iter__() 메서드를 호출해서 그 결과로 이터레이터(iterator) 객체를 반환 → 이터레이터 객체는 __next__() 메서드를 가지고 있어서 next()가 호출될 때마다 다음 값을 순차적으로 돌려줌
    2. __iter__()가 없으면 __getitem__() 검사
      • 만약 obj에 __iter__() 메서드가 없다면, 파이썬은 __getitem__() 메서드가 구현되어 있는지 확인함
      • __getitem__()은 인덱스를 받아서 값을 반환하는 메서드 → __getitem__() 메서드가 있으면 파이썬은 인덱스 0부터 하나씩 값을 꺼내는 방식으로 이터레이터를 생성함
    3. 이터레이터 생성 실패 시 예외 발생
      • 두 경우 모두 해당하지 않으면 TypeError 예외가 발생
      • "객체는 반복 가능하지 않다"는 메시지 호출
  • 이터레이터 객체의 역할
    • 이터레이터는 __next__() 메서드를 가지고 있어 next() 호출 시 차례대로 값을 반환함
    • 더 이상 반환할 값이 없으면 StopIteration 예외를 발생시켜 반복의 끝을 알림
  • iter() 함수의 두 번째 형태: iter(callable, sentinel)
    • iter(callable, sentinel) 형태로 사용할 때는 반복적으로 callable()을 호출하여 반환값이 sentinel과 같아질 때까지 값을 반환하는 이터레이터를 생성
  • 정리
    • iter()는 파이썬 객체가 반복 가능한지 판단하고, 반복에 사용할 이터레이터 객체를 만들어 주는 함수
    • 핵심: 객체의 __iter__() 메서드 호출
    • 해당 객체가 이미 이터레이터 객체라면 자기 자신을 반환하기도 함
    • 한 번 소비되면 다시 사용할 수 없으며, 새로운 반복을 시작하려면 다시 iter()를 호출해서 새 이터레이터를 만들어야 함

iter 함수와 next 함수

  • iter()와 next()는 파이썬에서 반복(iteration)과 관련된 역할을 하지만, 그 기능과 역할이 다름
  • iter 함수

    • 목적: 반복 가능한 객체(iterable; 리스트, 튜플, 문자열 등)를 이터레이터(iterator) 객체로 변환
    • 기능: 호출 시 해당 객체의 __iter__() 메서드를 호출해 이터레이터를 반환
      • 반환된 이터레이터 객체는 next()를 호출할 수 있는 메서드(__next__())를 가지고 있음
    • 결과: 이터레이터 객체를 얻음
      • 이터레이터는 값을 하나씩 순차적으로 꺼낼 수 있는 역할을 함
  • next 함수

    • 목적: 이터레이터(iterator)에서 다음 값을 하나씩 꺼내는 데 사용
    • 기능: 이터레이터의 __next__() 메서드를 호출해 다음 값을 반환함
    • 예외: 이터레이터의 요소를 모두 꺼내고 더 이상 값이 없으면 StopIteration 예외가 발생
  • iter와 next의 연결 관계
    • 먼저 iter() 함수를 통해 반복 가능한 객체를 이터레이터 객체로 만듦
    • 그 다음 next() 함수를 이용해 이 이터레이터 객체에서 하나씩 값을 꺼내 사용
    • 즉, iter()는 "이터레이터라는 반복용 객체"를 만드는 역할을 하고, next()는 그 이터레이터에서 "다음 데이터"를 꺼내는 역할을 하는 관계
  • 정리
    • iter()는 반복 가능한 자료구조를 반복용 객체로 바꾸고, next()는 그 반복용 객체에서 한 번에 하나의 값을 순차적으로 꺼내는 함수
    • 두 함수가 서로 협력하여 파이썬의 반복 구조를 이루는 핵심 요소

iter()를 무한 반복 탈출에 활용한 예시

  • iter() 함수는 호출 가능한 객체와 sentinel 값을 사용하는 특수한 반복문 탈출 기능과, 일반적인 이터레이터 생성 기능 두 가지 모두에서 무한 반복을 안전하게 제어하는 데 활용됨
  • 파이썬에서 iter() 함수를 무한 반복 탈출에 활용하는 대표적인 방법은 iter(호출가능한객체, sentinel) 형태를 사용하는 것
    • 이 형태는 매개변수 없는 호출가능한 객체(함수)를 반복적으로 호출하다가, 반환값이 미리 지정한 끝낼 값(sentinel) 과 같아지면 자동으로 반복을 중지함
  • 무작위 숫자를 계속 생성하다가 특정 값이 나오면 반복을 멈추는 코드:
import random

# 무작위로 0~5 사이 숫자를 생성하는 람다 함수
random_gen = lambda: random.randint(0, 5)

# 2가 나올 때까지 iter가 호출, 2가 나오면 자동 종료
for num in iter(random_gen, 2):
    print(num, end=' ')
  • 위 코드는 2가 나올 때까지 무한히 랜덤 수를 출력하다가 2가 나오면 자동으로 반복을 종료함
    • 즉, while True와 if ... break를 따로 작성하지 않아도 됨
  • 더 전통적인 방법은 iter()와 next()를 사용하되 StopIteration 예외를 잡아 무한 루프를 빠져나오는 방식:
lst = [1, 2, 3]
it = iter(lst)

while True:
    try:
        num = next(it)
        print(num)
    except StopIteration:
        break
  • 위 코드는 이터레이터가 끝날 때 발생하는 예외를 이용해 반복을 종료하는 기본적인 패턴
profile
2 B R 0 2 B

0개의 댓글