파이썬 목록과 혼동 : 그것들이 반복자입니까?


81

저는 Alex Marteli의 Python in a Nutshell을 연구하고 있으며이 책은 next()메서드가 있는 모든 객체가 반복자 (또는 적어도 사용할 수 있음)라고 제안 합니다 . 또한 iter.

책에서 이것을 읽은 후 나는 그것을 시도하고 싶은 충동을 느꼈다. 나는 파이썬 2.7.3 인터프리터를 시작하고 이렇게했습니다.

>>> x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for number in range(0, 10):
...     print x.next()

그러나 결과는 다음과 같습니다.

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
AttributeError: 'list' object has no attribute 'next'

혼란스러워서 x 객체의 구조를 비아로 연구하려고했는데 함수 객체 dir(x)가 있다는 것을 알았습니다 __iter__. 그래서 나는 그것이 그 유형의 인터페이스를 지원하는 한 반복자로 사용할 수 있다는 것을 알아 냈습니다.

그래서 다시 시도했을 때 이번에는 약간 다르게 시도했습니다.

>>> _temp_iter = next(x)

이 오류가 발생했습니다.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list object is not an iterator

그러나 목록이이 인터페이스를 지원하는 것처럼 보이므로 반복자가 아닐 수 있으며 다음 컨텍스트에서 목록으로 확실히 사용할 수 있습니다.

>>> for number in x:
...     print x

누군가 내 마음에서 이것을 명확하게 도울 수 있습니까?

답변:


107

그것들은 반복 가능 하지만 반복자 가 아닙니다 . iter()묵시적으로 (예를 들어를 통해 for) 또는 명시 적으로 반복자를 가져 오기 위해 전달 될 수 있지만 그 자체로는 반복기가 아닙니다.


11
주 (잘 동작 할) 모든 반복자는 반복 가능한 것을 - 그들의 next단순히 반환 self, 당신이 호출 할 수 있도록 iter(iter(iter(iter(x))))하고 같은 일을 얻을 iter(x). 이것이 for타입 스니핑없이 이터 러블과 이터레이터 모두에서 작동하는 이유입니다 (성능 최적화는 무시 함).

13
@delnan 당신은 "그들이 iter단순히 반환 self" 을 의미한다고 생각합니다 .
Lauritz V. Thaulow

다음 질문은 물론입니다. 반복자가되지 않도록 설계된 이유 는 무엇입니까?
gerrit

2
@gerrit : 반복자는 임의 액세스를 지원하지 않기 때문입니다.
Ignacio Vazquez-Abrams

1
@ IgnacioVazquez-Abrams "지원 안 함"이 요구 사항입니까? 나는 요구 사항 / 계약이 일반적으로 긍정적이고, X가 갖지 못하는 능력을 가지면서도 여전히 X (X가 할 수있는 모든 것을 할 수 있다는 의미에서)가 될 수 있다고 생각했습니다.
gerrit

26

먼저 다음을 사용하여 목록을 반복자로 변환해야합니다 iter().

In [7]: x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [8]: it=iter(x)

In [9]: for i in range(10):
    it.next()
   ....:     
   ....:     
Out[10]: 0
Out[10]: 1
Out[10]: 2
Out[10]: 3
Out[10]: 4
Out[10]: 5
Out[10]: 6
Out[10]: 7
Out[10]: 8
Out[10]: 9

In [12]: 'next' in dir(it)
Out[12]: True

In [13]: 'next' in dir(x)
Out[13]: False

객체가 반복자인지 여부 확인 :

In [17]: isinstance(x,collections.Iterator)
Out[17]: False

In [18]: isinstance(x,collections.Iterable)
Out[18]: True

In [19]: isinstance(it,collections.Iterable) 
Out[19]: True

In [20]: isinstance(it,collections.Iterator)
Out[20]: True

22

iterables와 iterators의 차이점이 무엇인지 혼란 스러울 경우를 대비하여. 반복기는 데이터 스트림을 나타내는 개체입니다. 반복기 프로토콜을 구현합니다.

  • __iter__ 방법
  • next 방법

반복기의 next () 메서드에 대한 반복 호출은 스트림에서 연속 항목을 반환합니다. 더 이상 데이터를 사용할 수없는 경우 반복기 객체가 고갈되고 next () 메서드에 대한 추가 호출은 StopIteration을 다시 발생시킵니다.

다른 쪽에서 반복 가능한 객체는 __iter__ 호출 될 때 반복자를 반환하는 메서드를 데이터를 여러 번 전달할 수 있습니다. 반복 가능한 객체는 재사용 가능하며, 소진되면 다시 반복 할 수 있습니다. iter함수를 사용하여 반복자로 변환 할 수 있습니다 .

따라서 목록 (반복 가능)이 있으면 다음을 수행 할 수 있습니다.

>>> l = [1,2,3,4]
>>> for i in l:
...     print i,
1 2 3 4
>>> for i in l:
...     print i,
 1 2 3 4

목록을 반복자로 변환하는 경우 :

>>> il = l.__iter__()  # equivalent to iter(l)
>>> for i in il:
...     print i,
 1 2 3 4
>>> for i in il:
...     print i,
>>> 

7

List는 iterator가 아니지만 list에는 iterator 객체가 포함되어 __iter__있으므로 모든 목록에서 for 루프를 사용하려고하면 for 루프가 __iter__메서드를 호출 하고 iterator 객체를 가져온 다음 list의 next () 메서드를 사용합니다.

x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
it = x.__iter__()

이제 StopIteration 예외가 발생할 때까지 사용할 수있는 it반복기 객체를 포함합니다.xit.next()


3
어떤 ... 결과AttributeError: 'list' object has no attribute 'iter'
전자 초밥

예 iter 속성이 없다는 것을 알고 있으며 iter method 전후에 2 개의 밑줄을 넣어야합니다 __iter__. 스택 오버플로는 내 대답에서 언급 한 밑줄을 대체하여 굵은 문자로 변환합니다. 나는이 일을 모르고 있었다
Kaushal

python3의에서 it.next()인상 AttributeError: 'list_iterator' object has no attribute 'next'. 대신이next(it)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.