Python의 반복자 이해

黄舟
풀어 주다: 2016-12-16 11:38:48
원래의
1045명이 탐색했습니다.

반복이란?

for 루프에서 직접 사용할 수 있는 객체를 총칭하여 반복 가능한 객체(Iterable)라고 합니다.
next() 함수에 의해 호출되어 계속해서 다음 값을 반환하는 객체를 반복자(iterator)라고 합니다.
모든 Iterable은 내장 함수 iter()를 통해 Iterator로 변환될 수 있습니다.

반복자의 경우 __next__() 하나만 있으면 충분합니다. for 및 in 문을 사용하면 프로그램은 처리할 객체의 반복자 객체를 자동으로 호출한 다음 StopIteration 예외가 감지될 때까지 __next__() 메서드를 사용합니다.

>>> L = [1,2,3]
>> [L의 x에 대한 x**2]
[1, 4, 9]
>>> next(L)
추적(가장 최근 호출 마지막):
파일 "", 첫 번째 줄,
TypeError: 'list ' 객체는 반복자가 아닙니다
>>> I=iter(L)
>>> next(I)
1
>> )
2
>>> next(I)
3
>>> next(I)
추적(가장 최근 호출 마지막):
파일 "", 1행,
StopIteration

위의 예에서 목록 L은 for로 반복할 수 있지만 내장된 검색으로는 검색할 수 없습니다. function next() 다음 값이므로 L은 Iterable입니다.
L은 iter에 의해 패키징되고 I로 설정됩니다. next()에서 다음 값을 찾는 데 사용될 수 있으므로 I는 Iterator입니다.

여담:

내장 함수 iter()는 객체의 __iter__() 메서드만 호출하므로 __iter__() 메서드는 목록 객체 내에 존재해야 합니다

내장 함수 next()는 객체의 __next__() 메서드만 호출하므로 __next__() 메서드는 목록 객체 내부에 존재하면 안 되지만, 이 메서드는 Itrator에 존재해야 합니다.

실제로 for 루프 내에서는 루프 반복 전에 Iterable을 Iterator로 변환하기 위해 iter()가 먼저 호출됩니다.

>>> L = [4,5,6]
>> I = L.__iter__()
>>> )
추적(가장 최근 호출 마지막):
파일 "", 첫 번째 줄,
AttributeError: 'list' 객체에 '__next__' 속성이 없습니다
> ;>> I.__next__()
4
>>> from collections import Iterator, Iterable
>>> isinstance(L, Iterable)
True >>>> isinstance(L, Iterator)
False
>>> isinstance(I, Iterable)
True
>>> )
True
>>> [x**2 for x in I]
[25, 36]

Iterator는 아래 테스트에서 Iterable을 상속합니다. Iterator에는 __iter__() 및 __next__() 메서드가 포함되어 있지만 Iteratble에는 __iter__()만 포함되어 있음을 쉽게 알 수 있습니다.

>>> from collections import Iterator, Iterable

>>> help(Iterator)
클래스 Iterator에 대한 도움말:

class Iterator(Iterable)
| 메소드 결정 순서:
| Iterable
| 내장형 개체
|**참고: 여기에서 Iterable은 Iterable을 상속하는 것을 볼 수 있습니다. .
| 여기에 정의된 메서드:
|
| __iter__(self)
|
| __next__(self)
| 소진되면 StopIteration을 발생시킵니다. 🎜>......
>>> help(Iterable)
Iterable 클래스에 대한 도움말:

class Iterable(builtins.object)
|
|
| __iter__(self)
......


iterable은 반복자를 반환하기 위해 __iter__() 메서드를 포함해야 하며, 반복자는 _를 포함해야 합니다. _next__() 메서드는 반복되는 데 사용됩니다

반복자를 직접 정의하는 경우 클래스에 __iter__() 함수를 정의하고 이를 사용하여 __next__() 메서드로 객체를 반환하는 것으로 충분합니다.

코드로 직접 이동

class Iterable:
def __iter__(self):

return Iterator()


class Iterator:
def __init__(self) :
self.start=-1
def __next__(self):
self.start +=2
if self.start >10:
StopIteration을 올립니다
self를 반환합니다. 시작

I = Iterable()
for i in I: PRint(i)

위 코드는 10 이내의 홀수를 찾는 코드입니다. 코드의 클래스 이름은 위에서 제공한 클래스 이름을 사용할 필요는 없습니다.
Iterator의 __next__ 메서드에서 StopIteration 예외가 구현되지 않은 경우 모든 홀수가 표시되면 호출 시 루프 종료 조건을 설정해야 합니다.

class Iterable:
def __iter__(self):
return Iterator()

class Iterator:
def __init__(self):
self.start= -1
def __next__(self):
self.start +=2
return self.start

I = Iterable()
개수의 경우 i in zip(range( 5),I): # 내장 함수 enumerate를 사용하여 계산 작업을 구현할 수도 있습니다.
print(i)

range를 사용하여 인쇄할 요소 수를 파악합니다. 여기서는 5개의 요소를 인쇄하는 것을 의미하며 반환 결과는 위와 일치합니다.

물론 이 두 클래스를 병합하여 프로그램을 단순화할 수 있습니다.
최종 버전은 다음과 같습니다

class Iterable:
def __iter__(self):
return self
def __init__(self):
self.start=-1
def __next__(self):
self.start +=2
if self.start >10:
raise StopIteration
return self.start

I = Iterable ()
for i in I:
print(i)

복사 반복자

반복자는 일회용 소모품이며 사용 후에는 비어 있게 됩니다. 다음을 참조하세요. .

>>> L=[1,2,3]
>> I=iter(L)
>>>
... print(i, end='-')
...
1-2-3-
>>>next(I)
추적(가장 최근 호출 마지막):
파일 "", 1행,
StopIteration

루프가 모두 소모되면 다시 호출됩니다. StopIteration 예외입니다.

다음에 사용할 수 있도록 직접 할당을 통해 반복자를 저장하고 싶습니다.
그런데 아래 예에서 볼 수 있듯이 전혀 작동하지 않습니다.

>>>I=iter(L)
>>>J=I
>>>다음(I)
1
>>> 다음(J)
2
>>> 다음(I)
3
>>> 다음(J)
최근 호출 마지막):
파일 "", 1행,
StopIteration

그러면 우리가 원하는 효과를 어떻게 얻을 수 있을까요?
복사 패키지에서 deepcopy를 사용해야 합니다. 아래를 참조하세요.

>>> import copy
>>> ;>>J=copy.deepcopy(I)
>>>다음(I)
1
>>다음(I)
2
>>> next(J)
1

보충: 반복자는 뒤로 이동하거나 처음으로 돌아갈 수 없습니다.

따라서 뒤로 이동과 같은 기능을 구현하려면 몇 가지 특별한 작업을 수행해야 합니다.

위 코드는 Python 3.4에서 테스트되었습니다.

위 내용은 Python의 Iterator를 이해하는 내용입니다. 더 많은 관련 글은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!



관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿