Explanation of the Difference between Generator and Iterator in Python

Source: Internet
Author: User
Keywords python generator iterator

A generator is a special type of iterator. so what is the difference between a generator and an iterator?

Iterator

 
definition:
For list, string, tuple, dict and other container objects, it is convenient to use for loop traversal. In the background, the for statement calls the iter() function on the container object. iter() is a Python built-in function.
The iter() function returns an iterator object that defines the next() method, which accesses the elements in the container one by one in the container. next() is also a Python built-in function. When there are no subsequent elements, next() will throw a StopIteration exception to notify the end of the for statement loop.
The iterator is used to help us record the location visited in each iteration. When we use the next() function on the iterator, the iterator will return to us the data of the next position of the recorded position. In fact, when using the next() function, the _next_ method of the iterator object is called (the object's _next_ method in Python3, and the object's next() method in Python2). Therefore, if we want to construct an iterator, we must implement its next method. But this is not enough. Python requires the iterator itself to be iterable, so we also need to implement the _iter_ method for the iterator, and the _iter_ method should return an iterator, the iterator itself is an iterator, so iterate The _iter_ method of the device returns itself.
 

Explanation of some terms:
1. Iterator protocol: The object needs to provide the next() method, which either returns the next item in the iteration, or causes a StopIteration exception to terminate the iteration.
2. Iterable object: implements the iterator protocol object. List, tuple, and dict are all Iterable (iterable objects), but not Iterator (iterator objects). But you can use the built-in function iter() to turn these into Iterable (iterator objects).
3. The essence of the for item in Iterable loop is to first obtain the iterable of the iterable object Iterable through the iter() function, and then continuously call the next() method on the obtained iterator to obtain the next value and assign it to the item, When the exception of StopIteration is encountered, the loop ends

 

Example of Python's own container object:

# Randomly define a list
listArray=[1,2,3]
# Use the iter() function
iterName=iter(listArray)
print(iterName)
# The result is as follows: is an iterator of list
# <list_iterator object at 0x0000017B0D984278>
 
print(next(iterName))
print(next(iterName))
print(next(iterName))
print(next(iterName))# Without iterating to the next element, an exception is thrown directly

# Traceback (most recent call last):
# File "Test07.py", line 32, in <module>
# StopIteration

A class object in Python that implements the _iter_ method and _next_ method is an iterator. The following case is a case of calculating the Fibonacci sequence


class Fib(object):
 def __init__(self, max):
  super(Fib, self).__init__()
  self.max = max
 
 def __iter__(self):
  self.a = 0
  self.b = 1
  return self
 
 def __next__(self):
  fib = self.a
  if fib> self.max:
   raise StopIteration
  self.a, self.b = self.b, self.a + self.b
  return fib
 
# Define a main function, loop through each Fibonacci number
def main():
 # Numbers within 20
 fib = Fib(20)
 for i in fib:
  print(i)
 
# Test
if __name__ =='__main__':
 main()

explain:

In the implementation of this class, a _iter_(self) method is defined. This method is called by iter() during the for loop traversal and returns an iterator. Because during the traversal, the built-in python function iter() is called directly, and iter() obtains the iterator of the object by calling _iter_(self). With iterators, you can iterate over the elements one by one. When traversing one by one, it also uses the built-in next() function to traverse the iterator object by calling the object's _next_(self) method. Therefore, we must implement the two methods _iter_(self) and _next_(self).
And because the _next_(self) method is implemented, when _iter_(self) is implemented, it is sufficient to return to self directly.
The summary is:
When looping through a custom container object, it will use the Python built-in function iter() to call the _iter_(self) of the traversal object to obtain an iterator, and then recycle the next_() to call the iterator object's _next_() self).
Note: _iter_(self) will only be called once, and _next_(self) will be called n times, until StopIteration exception occurs.
 

generator
 

effect:
>Delayed operation. That is, results are produced when needed, not immediately.

 

Precautions:
>The generator can only be traversed once.
> Generator is a special kind of iterator.

 

classification:
The first category: generator functions: still use def to define functions, but use yield instead of return statements to return results. The yield statement returns one result at a time, and in the middle of each result, suspend the state of the function so that execution can continue from where it left next time.
The following cases are illustrated:


# Fibonacci sequence
def Fib(max):
 n, a, b = 0, 0, 1
 while n <max:
  yield b
  a, b = b, a + b
  n = n + 1
 return'Dear! No more data...'
# Call the method and generate 10 numbers
f=Fib(10)
# Use a loop to capture the value returned by the last return and save it in the value of the exception StopIteration
while True:
 try:
  x=next(f)
  print("f:",x)
 except StopIteration as e:
  print("The final return value of the generator is:",e.value)
  break

The second type: generator expressions: similar to list comprehension, except that a pair of braces [] is transformed into a pair of parentheses (). However, the generator expression is to generate a generator result object on demand. To get each element, you need to loop through it.
The following cases are illustrated:

# A list
xiaoke=[2,3,4,5]
# Generator generator, similar to list, but changed [] to ()
gen=(a for a in xiaoke)
for i in gen:
 print(i)
#The result is:
2
3
4
5
 
# Why use a generator? Because of efficiency.
# Use generator expressions instead of list comprehensions to save both cpu and memory (RAM).
# If the purpose of constructing a list is to pass it to other functions,
# For example to pass to tuple() or set(), then use generator expression instead!
 
# This case is to directly convert the list into a tuple
kk=tuple(a for a in xiaoke)
print(kk)
#The result is:
(2, 3, 4, 5)
 
# Some built-in functions of Python can recognize that this is a generator expression, and there is a pair of parentheses outside, which is a generator
result1=sum(a for a in range(3))
print(result1)
# List comprehension
result2=sum([a for a in range(3)])
print(result2)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.