문제의 역사
enumerate() 함수는 파이썬에서 시퀀스의 요소를 반복(iteration)하면서 현재 인덱스를 동시에 얻기 위해 도입되었습니다. 이는 특히 중요합니다. 이전에는 별도의 카운터를 수동으로 생성하는 것이 권장되었지만, 이는 비아이디오매틱하고 읽기가 어려운 것으로 간주되었습니다.
문제
루프에서 현재 값뿐만 아니라 시퀀스 내에서의 인덱스도 알고 싶을 때가 많습니다. 별도의 변수(i)와 함께 range(len(seq))를 사용하는 방식은 오류(인덱스와 값의 불일치, 코드 중복)를 유발하고 가독성을 저하시킵니다.
해결책
enumerate()는 각 단계에서 현재 요소의 (인덱스, 값) 튜플을 반환하는 지연 반복기(lazy iterator)를 제공합니다. 이를 통해 인덱스와 우아하고 신뢰성 있게 작업할 수 있습니다:
colors = ['red', 'green', 'blue'] for idx, color in enumerate(colors): print(idx, color)
반복은 0부터 시작하지만, 시작 값을 다른 값으로 지정할 수 있습니다:
for idx, color in enumerate(colors, start=1): print(idx, color)
주요 특징:
enumerate()는 모든 반복 가능한 시퀀스에서 작동하며 (인덱스, 요소) 튜플을 반환합니다.start 오프셋을 지정할 수 있어 편리합니다.enumerate()를 사용할 때 인덱스 반환을 비활성화하고 값만 남길 수 있나요?
아니요, enumerate()는 항상 (인덱스, 값) 쌍을 반환합니다. 값만 필요하다면 일반적인 for 루프를 사용하십시오:
for value in my_list: print(value)
enumerate()를 인덱스가 없는 객체로, 예를 들어 제너레이터와 함께 사용할 수 있나요?
예, enumerate()는 제너레이터를 포함한 모든 반복 가능한 객체에서 작동합니다. 인덱싱은 값이 나타나는 순서에 따라 이루어집니다:
def mygen(): for i in range(3): yield chr(ord('a')+i) for idx, val in enumerate(mygen()): print(idx, val) # 0 a, 1 b, 2 c
0이 아닌 시작 인덱스를 자동으로 지정할 수 있으며, 음수 값을 사용할 경우 어떻게 되나요?
예, enumerate()에는 start 인수가 있습니다. 음수 값을 전달하면 인덱싱이 해당 값에서 시작됩니다:
for idx, x in enumerate(['a', 'b', 'c'], start=-3): print(idx, x) # -3 a, -2 b, -1 c
range(len(seq)) 대신 enumerate()를 사용하는 것 — 이렇게 하면 코드가 덜 읽기 쉽게 되고 아이디오매틱하지 않게 됩니다.팀은 큰 코드를 유지하며 자주 다음과 같이 사용합니다:
for i in range(len(mylist)): process(i, mylist[i])
장점:
단점:
리팩토링 후 다음과 같이 변경합니다:
for idx, val in enumerate(mylist): process(idx, val)
장점:
단점: