Python-Iterator

Posted by Nommy on Tue, 30 Jul 2019 14:03:47 +0200

Articles Catalogue

iterator

Iterable objects:

list, str, tuple, etc -> for... in... Traverse - > Traverse (Iteration)

Iterator protocol: The object must provide a next method that either returns to the next item in the iteration or causes a StopIteration exception to terminate the iteration (only go down, not go back)

Now, we can say that the object that implements the iterator protocol is the iteratable object.

How to achieve it?

  • By defining a _iter_ method inside the object
li=[1,2,3]
sr='ab'
li_iter=li.__iter__()  # <--->iter(li)
sr_iter=iter(sr)
print(li_iter.__next__())   # <--->next(li_iter)
print(li_iter.__next__())
print(next(li_iter))
print(next(sr_iter))
print(next(sr_iter))
print(next(sr_iter))      # Out-of-range StopIteration anomaly

    print(next(sr_iter))
StopIteration
1
2
3
a
b

collections

from collections import Iterable # Use instance() to determine whether an object can be iterated
print(isinstance([],Iterable))
print(isinstance(str(),Iterable))
print(isinstance({},Iterable))
print(isinstance(set(),Iterable))
print(isinstance(123,Iterable))
print(isinstance(True,Iterable))

True
True
True
True
False
False

Customize a class that can hold data and test its iterativeness

from collections import Iterable
class MyClass:
    def __init__(self):
        self.names=[]
    def add(self,name):
        self.names.append(name) 
    def __iter__(self):        # Do not add as non-iterative object
        return self.names.__iter__()
my_class=MyClass()
my_class.add('Tom')
my_class.add('Jack')
print(my_class.names)
print(isinstance(my_class,Iterable))
for i in my_class:
    print(i,end=' ')
    
['Tom', 'Jack']
True
Tom Jack 

Looking back at the _iter_ method, which we mentioned earlier, it can provide us with an iterator

When iterating over an iteratable object, it is actually an iterator provided by that object. The iterator then retrieves each data of the object in turn.

for... in... The Nature of Cycle

Iterable iterator is obtained by iter() function, and then the next() method is called to obtain the next value and assign the item to the obtained iterator. When the StopIteration exception is encountered, the iterator exits.

class test:
    def __init__(self,data=1):
        self.data=data
    def __iter__(self):
        return self
    def __next__(self):
        if self.data>5:
            raise StopIteration
        else:
            self.data+=1
            return self.data
for i in test(2):
    print(i,end=' ')
    
3 4 5 6

Application scenarios

The core of the iterator is to return the next data value through the next() function call. If the data value returned each time is not read in an existing data set, but generated by the program according to certain rules. That means that you don't need to rely on an existing data set, namely, and you don't need to cache all the iterated object data at one time for subsequent use. In this way, a large amount of storage (memory) space can be saved.

demo:

Fibonacci sequence

Now we hope to pass for ____________. In... The way to traverse the first n numbers in the Fibonacci sequence

By iteration, each iteration can generate the next number by mathematical calculation.

# Two initial values
# N, not greater than the value of n-like indexes
class Fib(object):
    """Fibolacci Sequence Generation Iterator"""
    def __init__(self,n):

        # Number of Fibonacci sequence generated by recording
        self.n=n
        #Index to record current records
        self.current_index=0
        # Record two initial values
        self.num1=0
        self.num2=1

    def __next__(self):
        """call next()Function to get the next number"""
        if self.current_index<self.n:
            num=self.num1
            self.num1,self.num2=self.num2,self.num1+self.num2
            self.current_index+=1
            return num
        else:
            raise StopIteration
    def __iter__(self):
        return self

fib=Fib(10)
for num in fib:
    print(num,end=' ')
    
0 1 1 2 3 5 8 13 21 34