Understand Python iterators

Source: Internet
Author: User
Understand Python iterators

What is iteration?

Objects that can directly act on the for loop are collectively referred to as Iterable objects ).
The object that can be called by the next () function and continuously return the next value is called an Iterator ).
All Iterable can be converted to Iterator through the built-in function iter.

For the iterator, it is enough to have a _ next. When you use the for and in statements, the program automatically calls the iterator object of the object to be processed, and then uses its _ next _ () method, A StopIteration exception is detected.

>>> L = [1, 2, 3]
>>> [X ** 2 for x in L]
[1, 4, 9]
>>> Next (L)
Traceback (most recent call last ):
File" ", Line 1, in
TypeError: 'list' object is not an iterator
>>> I = iter (L)
>>> Next (I)
1
>>> Next (I)
2
>>> Next (I)
3
>>> Next (I)
Traceback (most recent call last ):
File" ", Line 1, in
StopIteration

In the above example, list L can be cyclically executed by for, but cannot be used by the built-in function next () to find the next value, so L is Iterable.
L after being packaged by iter, set it to I. I can be used by next () to find the next value, so I is an Iterator.

Digress:

The built-in function iter () only calls the _ iter _ () method of the object. Therefore, the list object must have the _ iter _ () method __()

The built-in function next () only calls the _ next _ () method of the object. Therefore, the list object must not have the _ next _ () method __(), however, this method must exist in Itrator.

In fact, the for loop first calls iter () to convert Iterable into Iterator for loop iteration.

>>> L = [4, 5, 6]
>>> I = L. _ iter __()
>>> L. _ next __()
Traceback (most recent call last ):
File" ", Line 1, in
AttributeError: 'list' object has no attribute '_ next __'
>>> I. _ next __()
4
>>> From collections import Iterator, Iterable
>>> Isinstance (L, Iterable)
True
>>> Isinstance (L, Iterator)
False
>>> Isinstance (I, Iterable)
True
>>> Isinstance (I, Iterator)
True
>>> [X ** 2 for x in I]
[25, 36]

Iterator inherits from Iterable. in the following test, we can easily see that Iterator contains the _ iter _ () and _ next _ () methods, iteratble only contains _ iter __().

>>> From collections import Iterator, Iterable
>>> Help (Iterator)
Help on class Iterator:

Class Iterator (Iterable)
| Method resolution order:
| Iterator
| Iterable
| Builtins. object
| ** Note: Here we can see that Iterable inherits from object, and Iterator inherits from Iterable.
| Methods defined here:
|
| _ Iter _ (self)
|
| _ Next _ (self)
| Return the next item from the iterator. When exhausted, raise StopIteration
......
>>> Help (Iterable)
Help on class Iterable:

Class Iterable (builtins. object)
| Methods defined here:
|
| _ Iter _ (self)
......

Iterable must contain the _ iter _ () method to return iterator, and the iterator must contain the _ next _ () method to be recycled.

If we define the iterator ourselves, we only need to define a _ iter _ () function in the class and use it to return a function with _ next __() the method object is enough.
Directly add code

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:
Raise StopIteration
Return self. start

I = Iterable ()
For I in I: PRint (I)

The code above finds an odd number within 10. the class name in the code can be obtained at will, rather than the class name provided above.
If the StopIteration exception is not implemented in the _ next _ method of Iterator, it indicates all the odd numbers. Therefore, you must set the exit loop condition during the call.

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 ()
For count, I in zip (range (5), I): # You can also use the built-in function enumerate to implement counting.
Print (I)

We use range to print the number of elements. Here, five elements are printed, and the returned results are the same as those above.

Of course, we can combine these two classes to simplify the program.
The final version is as follows:

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)

Copy iterator

The iterator is a one-time consumable and will be empty after use. please refer.

>>> L = [1, 2, 3]
>>> I = iter (L)
>>> For I in I:
... Print (I, end = '-')
...
1-2-3-
>>> Next (I)
Traceback (most recent call last ):
File" ", Line 1, in
StopIteration

When the loop is used up, the StopIteration exception is thrown when the call is used again.

We want to save the iterator by directly assigning values, which can be used next time.
However, we can see from the following example that it is useless.

>>> I = iter (L)
>>> J = I
>>> Next (I)
1
>>> Next (J)
2
>>> Next (I)
3
>>> Next (J)
Traceback (most recent call last ):
File" ", Line 1, in
StopIteration

So how can we achieve what we want?
We need to use deepcopy in the copy package. please refer to the following:

>>> Import copy
>>> I = iter (L)
>>> J = copy. deepcopy (I)
>>> Next (I)
1
>>> Next (I)
2
>>> Next (J)
1

Supplement: The iterator cannot move backward or return to the start.
So we need to do some special things to implement backward movement and other functions.

The above code has passed the test in Python 3.4.

The above is the content of the Python iterator. For more articles, please follow the PHP Chinese network (www.php1.cn )!

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.