반복이란?
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)
추적(가장 최근 호출 마지막):
파일 "
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]
>>> 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__() 메서드는 반복되는 데 사용됩니다
코드로 직접 이동
class Iterable:
def __iter__(self):
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)
추적(가장 최근 호출 마지막):
파일 "
StopIteration
루프가 모두 소모되면 다시 호출됩니다. StopIteration 예외입니다.
다음에 사용할 수 있도록 직접 할당을 통해 반복자를 저장하고 싶습니다.
그런데 아래 예에서 볼 수 있듯이 전혀 작동하지 않습니다.
>>>I=iter(L)
>>>J=I
>>>다음(I)
1
>>> 다음(J)
2
>>> 다음(I)
3
>>> 다음(J)
최근 호출 마지막):
파일 "
StopIteration
그러면 우리가 원하는 효과를 어떻게 얻을 수 있을까요?
복사 패키지에서 deepcopy를 사용해야 합니다. 아래를 참조하세요.
>>> import copy
>>> ;>>J=copy.deepcopy(I)
>>>다음(I)
1
>>다음(I)
2
>>> next(J)
1
따라서 뒤로 이동과 같은 기능을 구현하려면 몇 가지 특별한 작업을 수행해야 합니다.