Python Iteration object, iterator, Generator Detailed

Source: Internet
Author: User
Tags iterable prev

in understanding Python Data structure, container (container), Iterationobject (iterable), iterator (iterator) , Generator (generator) , List / Collection / Dictionary Derivation type (list,set,dict Comprehension) a lot of concepts mixed together, It is inevitable for beginners to confused, This article will be one for everyone to introduce, hope to learn python to help You.

Container (container)

a container is a data structure that organizes multiple elements together, and the elements in a container can be iterated over one after another, using in, the not keyword, to determine whether an element is contained in a container. Usually such data structures store all the elements in memory (and some are not all elements in Memory) in Python , common container objects are:

list, deque, ....

set, frozensets, ....

dict, defaultdict, ordereddict, Counter, ....

tuple, namedtuple, ...

Str

the container is easier to understand because you can think of it as a box, a house, a cupboard, which can be stuffed with anything. technically, when it can be used to ask if an element is contained in it, then the object can be considered a container, such as list,set,tuples are container objects:

>>> assert 1 in [1, 2, 3] # Lists

>>> assert 4 not in [1, 2, 3]

>>> assert 1 in {1, 2, 3} # Sets

>>> assert 4 not in {1, 2, 3}

>>> assert 1 in (1, 2, 3) # tuples

>>> assert 4 not in (1, 2, 3)

ask if an element is in dict with the dict key:

>>> d = {1: ' foo ', 2: ' bar ', 3: ' Qux '}

>>> assert 1 in D

>>> assert ' foo ' not in D # ' foo ' is not an element in dict

ask if a substring is in string :

>>> s = ' foobar '

>>> assert ' B ' in S

>>> assert ' X ' not in S

>>> assert ' foo ' in S

While the vast majority of containers provide some way to get each of these elements, this is not the ability provided by the container itself, but rather can iterate over objects the ability to give a container, of course, is not all containers are iterative, such as: Bloom filter , although Bloom filter can be used to detect whether an element is contained in a container, it is not possible to obtain each of these values in a single device, because Bloom filter instead of storing the element in a container, it is mapped to a value stored in the array by a hash function.

can iterate over objects (iterable)

as mentioned earlier, Many containers are iterative objects, and there are more objects that are also iterative objects, such as files that are open,sockets , and so On. But the object that can return an iterator can be called an iterative object, which may sound a bit confusing, but let's look at an example:

>>> x = [1, 2, 3]

>>> y = iter (x)

>>> z = iter (x)

>>> Next (y)

1

>>> Next (y)

2

>>> Next (z)

1

>>> type (x)

<class ' list ' >

>>> type (y)

<class ' List_iterator ' >

here x is an iterative object, iterative objects and containers is a popular term, not a specific data type,list is an iterative object,dict  is an iterative object, andset is also an iterative object. y and z are two independent iterators that hold a state inside the iterator that records where the current iteration is located, so that the correct element is available for the next Iteration. Iterators have a specific type of iterator, such as list_iterator , set_iterator . the __iter__ and __next__ methods are implemented in an iterative object (python2 C22>next method,python3 is the __next__ method), These two methods correspond to the built-in functions  ITER () and next () . the __iter__ method returns an iterator that iterates over the object itself, which makes him both an iterative object and an Iterator.

When running Code:

x = [1, 2, 3]

For Elem in X:

...

The actual performance is:


to decompile The code, you can see that the interpreter appears to call The get_iter instruction is equivalent to calling ITER (x) , and the for_iter instruction is invoking the next () method, Gets the next element in the iterator continuously, but you can't see it directly from the command, because he is optimized by the Interpreter.

>>> Import Dis

>>> x = [1, 2, 3]

>>> Dis.dis (' for _ in X:pass ')

1 0 setup_loop (to 17)

3 Load_name 0 (x)

6 Get_iter

>> 7 For_iter 6 (to 16)

Ten Store_name 1 (_)

7 Jump_absolute

>> Pop_block

>> Load_const 0 (None)

Return_value

iterators (iterator)

So what about iterators?  It is a stateful object that can return the next value in the container when you call the next () method, any implementation of __next__ () ( implemented in Python2 next () ) method is an iterator, and it does not matter how it is Implemented.

so, The iterator is the object that implements the factory pattern, and it returns you every time you ask for the next Value. There are many examples of iterators, such as the Itertools function that returns an iterator Object.

Generate an infinite sequence:

>>> from Itertools Import count

>>> counter = Count (start=13)

>>> Next (counter)

13

>>> Next (counter)

14

To generate an infinite sequence from a finite sequence:

>>> from Itertools Import cycle

>>> colors = Cycle ([' red ', ' white ', ' blue ')

>>> Next (colors)

' Red '

>>> Next (colors)

' White '

>>> Next (colors)

' Blue '

>>> Next (colors)

' Red '

To generate a finite sequence from an infinite sequence:

>>> from Itertools import islice

>>> colors = Cycle ([' red ', ' white ', ' Blue ']) # Infinite

>>> Limited = Islice (colors, 0, 4) # finite

>>> for X in Limited:

... print (x)

Red

White

Blue

Red

To get a more intuitive sense of the execution process inside an iterator, we customize an iterator that takes the Fibonacci sequence as an example:

Class Fib:

def __init__ (self):

Self.prev = 0

Self.curr = 1

def __iter__ (self):

return self

def __next__ (self):

Value = Self.curr

Self.curr + = Self.prev

Self.prev = value

return value

>>> f = Fib ()

>>> list (islice (f, 0, 10))

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

The Fib is both an iterative object (because it implements the __iter__ METHOD) and an iterator (because the __next__ method is implemented). Instance variables prev and curr users maintain the state inside the Iterator. Do two things each time you call the next () method:

Modify the state for the next call to the next () method

Generates a return result for the current call

An iterator is like a lazy-loaded factory that returns a value when someone needs it, and waits for the next call when it is not called.

Generator (generator)

Generator is a One of the most appealing features of the Python language, the generator is actually a special iterator, but this iterator is more elegant. It does not need to write the __iter__ () and __next__ () methods as in the class above , only one yiled keyword is required. The generator must be an iterator (and vice versa), so any generator also generates values in a lazy-loaded pattern. Examples of Fibonacci sequences implemented with generators are:

def fib ():

prev, Curr = 0, 1

While True:

Yield Curr

prev, Curr = curr, Curr + prev

>>> f = fib ()

>>> list (islice (f, 0, 10))

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

The FIB is an ordinary python function, where the function is not a return keyword, and the return value of the function is a generator object. When execution f=fib () Returns a generator object, the code in the body of the function does not execute, and the code is actually executed only when the next is shown or implicitly called .

Generator in Python is a very powerful programming structure that can write streaming code with less intermediate variables, and in addition, it can save memory and CPU compared to other container objects , of course, it can use less code to achieve similar Functions. Now it's time to refactor your code and see something like This:

def something ():

result = []

For ... in ...:

Result.append (x)

return result

Can be replaced with a generator function:

def iter_something ():

For ... in ...:

Yield x

Builder Expression (generator Expression)

A builder expression is a list-down version of the builder that looks like a list derivation, but it returns a generator object instead of a list object.

>>> A = (x*x for x in range (10))

>>> A

<generator Object <genexpr> at 0x401f08>

>>> sum (a)

285

Source: Public Account

Python Iteration object, iterator, Generator Detailed

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.