Iterator and Generator

iterator

The Meaning of Iteration

  1. repeat
  2. The next repetition is based on the results of the previous one.

Iterable objects and iterators

  1. In python, for ordered objects such as lists, tuples, and strings, elements can be traversed by indexing. Unordered objects such as dictionaries and collections cannot be indexed.
    In order to provide an index-independent iteration method, python has built-in obj.iter method for some objects: the obj with this method is called an iterative object.

  2. An iteratable object executes obj.iter() and the result is an iterator; iter(obj) is equivalent to obj.iter().

  3. Iterators have iter and next methods. Execute the Iterator.iter() method on an iterator to get the iterator itself. Each time an iterator executes the Iterator.next() method, an element can be iterated out.

  4. How to determine whether an object is an iterative object or an iterator:?

from collections import Iterable, Iterator   # Import module
isinstance(obj, Iterable)   # Determine whether obj is an instance of Iterable, and return it?True/False
isinstance(obj, Iterator)   # Judge whether obj is? Iterator Instance, returnTrue/False

Advantages of Iterators

  1. Provides an index-independent way to get values
  2. Lazy Computing, Save Memory

Disadvantages of iterators

  1. It's not as convenient to take values as it is to index them.
  2. One-time, you can only go backward, not forward, call obj.next() method to execute, and throw StopIteration after the last element iteration.
  3. Therefore, length cannot be obtained

for i in obj:

for i in obj:   # Execute obj = obj. _iter_()
    print(i)    # Execute obj. _next_(), give each return value to i and print it out until for captures StopIteration and ends.

Knowing this principle, we can also use the while method to achieve iteration.

l = [1,2,3,4]
l = iter(l)     # Converting lists into iterators
while True:
    print(next(l))  # Call the next method to iterate over the elements until the StopIteration is thrown

To avoid throwing StopIteration, try: exception: can be used to capture it and set the processing mode:

l = [1,2,3,4]
l = iter(l)
while True:
    try:    # Set try before statements that may have exceptions:
        print(next(l))
    except StopIteration:   # Capture StopIteration exception
        break   # exception handling

generator

Generator function:

The function body contains the yield keyword, and the result of execution of the function is the generator function.

def step():
    print('first-------->')
    yield 1
    print('second-------->')
    yield 2
    print('third-------->')
    yield 3
    print('fourth-------->')    # The function does not return at the end, and return None is executed by default.
# The execution function step() is a generator.
print(type(step())) # The print result is: <class'generator'>
g = step()
from collections import Iterator
print(isinstance(g, Iterator))
# The print result is True, so the generator is an iterator, and the method with an iterator _next__
print(next(g))  # Execute a next(g), (equivalent to g. next ()), trigger a function execution until yield is encountered, and print out the yield return value.
print(next(g))  #
print(next(g))
print(next(g))
print(next(g))

Functions of yield

  1. Similar to return, values can be returned, but multiple values can be returned through yield, while return can only be returned once.
  2. To encapsulate iter and next methods for functions, the results of function execution (function name +()) are made into iterators.
  3. Following the iterator's obj.next(), the execution of the trigger function is triggered, and the state of suspension and resumption of the function is saved by yield.

Example:

Counter

def countdown(n):
    print('starting counting')
    while n > 0:
        yield n     # When you encounter a yield pause, return the value of the current n and execute from the current place next time.
# Because the generator is also an iterator, it has the characteristics of iterator: one-time, can only go forward.
        n -= 1
    print('stop counting')
g = countdown(5)
print(next(g))  # next iterates over the elements of g until a StopIteration is thrown. In addition, the printing position of StopIteration is random.
...

We can also use the for i in g statement to automatically capture Stop Iteration to end the iteration:

for i in g:
    print(i)
# The results are as follows:
# starting counting
# 5
# 4
# 3
# 2
# 1
# stop counting

Note: By referring to the generator function countdown(5) to g, each execution of G iterates over the same generator and returns a continuous value. Each time countdown(5) is executed directly, a new generator is generated.

Keywords: Python

Added by Solemn on Sat, 22 Jun 2019 00:00:25 +0300