__python of iterators and generators in Python3

Source: Internet
Author: User
Tags generator iterable
iterator (iterator)
def add (S, x): return
 s + x

def gen ():
 for I in range (4):
  yield i

base = Gen ()
for n in [1, 10]:
  base = (Add (i, n) for I in base)

Print List (base)

The output of this thing can be brain mended, and the result is [20,21,22,23], not [10, 11, 12, 13].

To say generators, you must first say iterators
Distinguishing Iterable,iterator from Itertion
When it comes to iterators, you need to distinguish between several concepts: iterable,iterator,itertion, looks alike, but not. Here's a distinction.

Itertion: Iteration, one after another, is a common concept, such as looping through an array.
Iterable: This is an iterative object, belongs to the Python noun, the scope is also very wide, repeatable iterations, one of the following is iterable: Can for loop: for the I in iterable can be indexed by index object, which is defined GetItem methods, such as LIST,STR; The Iter method is defined. Be free to return. You can invoke the object of ITER (obj) and return a iterator

Iterator: An iterator object, also a python noun, can only be iterated once. The following iterator protocol needs to be met to define the Iter method, but it must return itself to define the next method, at python3.x is next. Used to return the next value, and when there is no data, throw the stopiteration to keep the current state

First STR and list are iterable but not iterator:

in [+]: si = iter (s) in [m]: si out[14]: <iterator at 0x7f9453279dd0>: si.__iter__ # __iter__ out[15]: <method-wrapper ' __iter__ ' of iterator object at 0x7f9453279dd0> in [[]: Si.next #拥有next out[16]: <method-wrapp Er ' next ' of iterator object at 0x7f9453279dd0> in [m]: si.__iter__ () is Si #__iter__返回自己 out[20]: True in [1]:%p Aste class Dataiter (object): Def __init__ (self, *args): Self.data = List (args) Self.ind = 0 def __iter__ (self): #返 Return self def next (self): # Back to data if Self.ind = = Len (self.data): Raise stopiteration else:data = self.  Data[self.ind] Self.ind + + 1 Return Data # #--End pasted text--in [9]: D = dataiter (1,2) in [ten]: for x in D: # Start iteration ...: Print x ...: 1 2 in []: D.next () # can only be iterated once, and then used again to throw an exception--------------------------------------------------- ------------------------stopiteration Traceback (most recent call last)----> 1 d.next () <ipython-input-1-c4 4abc1904d8> in next (sElf-def Next (self): one if self.ind = Len (self.data):---> Raise stopiteration else:14 da TA = Self.data[self.ind]

From the next function can only take the data forward, one can be seen, but not repeated data, then this could be solved.
We know that iterator can only iterate once, but the Iterable object does not have this limitation, so we can separate the iterator from the data and define a iterable and iterator as follows:

Class Data (object): # is just iterable: can iterate over objects without iterator: iterator

 def __init__ (self, *args):
  self.data = list (args)

 def __iter__ (self): # does not return its own returns
  Dataiterator (self)


class Dataiterator (object): # iterator: iterator

 def __ Init__ (self, data):
  self.data = data.data
  self.ind = 0

 def __iter__ (self): return
  self

 def next ( Self):
  if Self.ind = = Len (self.data):
   raise stopiteration
  else:
   data = Self.data[self.ind]
   Self.ind + 1 return
   data

if __name__ = = ' __main__ ':
 d = Data (1, 2, 3)
 for x in D:
  print x,
 For x in D:
  print x,


1,2,3
1,2,3

Python supports iterations on containers, implemented in two ways, allows user customization, and sequence always supports iterative methods.

The function of an iterator can be replaced by a list, but if there are many values, the list takes up too much memory, and if there is a function that can compute the value one by one, you can get a value when using a value and use less memory. iterators for variables, there are two methods Iter (), Next ()

When traversing an iterator, it modifies the internal state, cause you can only get the next element forward, and you cannot access the following element through an iterator; that is, after you have accessed an element through an iterator, you cannot go back and continue accessing the element in the current loop unless you re producing the iterator object for traversal.

#迭代器对于变量
list1=[1,2,3,4,5]
it1=iter (list1) print (Next (it1)) print (
next (it1)) print
(' = = ======= ') for
x in it1:
    print (x, end= ' \ n ')
print (' ============= ')

#可以使用next () function
list2=list (' ABCDEFG ')
It2=iter (list2) while

True:
    try:
        print (Next (it2))
    except stopiteration:
        Sys.exit ()

The output results are as follows:

1
2
=============
3
4
5
=============
a
b
c
d
e
F
g
for the class to return the iterator, implement iterator. ITER (), iterator. Next ()

The iterator object is required to support the following two methods, combined to form an iterative protocol.

Iterator. _iter_ ()

Returns the Iterator object itself. In order to allow containers and iterators to be used in the for and in statements, the method must be implemented.

Iterator. _next_ ()
Returns the next entry for the container. If there are no more entries, throw the stopiteration exception

Also note that the next method in the iterator is to return the value of the next element, unlike the one described below yield an element

Class fibs:
    def __init__ (self):  # initialize
        self.a = 0
        self.b = 1

    def __next__ (self):  # Get Next entry
        SELF.A, self.b = self.b, SELF.A + self.b
        return SELF.A

    def __iter__ (self):  # Returning iterator returns
        self

Fibs=fibs () for
F in fibs:
    if f >: Break
        
Builder (Generator)

Any function that uses yield is called a generator.

The first thing to be clear is that the generator is also a iterator iterator, because it follows the iterator protocol. The generator function is only a bit different from a normal function, which is to replace return with yield, where yield is a syntactic sugar that implements the iterator protocol internally, while maintaining state can be suspended.
(returns if replaced with return function)

Another argument: A generator is a function that returns an iterator, and the difference between a normal function is that the generator contains a yield statement, and it's simpler to understand that the generator is an iterator.

With yield, you can have a function generate a sequence that returns an object type of "generator", through which successive calls to the next () method return the sequence value.

The generator function begins executing the statement within the function only when the _next () _ method is invoked.
When the Count function is called: C=count (7) and does not print "Counting" only wait until the call to C. Next () to actually execute the statements inside. Each time you call the next() method, the Count function runs to the statement yield N, and the return value ofnext() is the build value n, which is printed to view the return value, which can be removed and called again next( method, the function continues to execute the statement after yield (a friend familiar with Java must know the Thread.yield () method, which is to suspend the current thread from running and let other threads execute it), such as:

The yield function is to return a generator, which saves the current function state, recording the next time the function is called Next, running state

A = (I for I with Range (4))
print (a) for
I in a:
    print (i) for
I in a:
    print (' = = ') print (
    i)

output only 0,1,2,3
def count (n):
    print ("cunting") while
    n > 0:
        print (' before yield ')
        yield n  # generates a value: N
        Print (n)
        N--= 1
        print (' after yield ')

C=count (7)
c.__next__ ()
#before yield
c.__next_ _ ()
# 7 # After the
yield
# before yield
c.__next__ ()
# 6
# after yield
# before yield

If you call the next method all the time, the program will complain when it executes to a value that does not have an iteration:

Traceback (most recent call last): File "", Line 1, in Stopiteration

So you don't typically call the next method manually, but use the For loop

For I in Count (5):  
    print (i)
def Fibonacci (N): # generator Function-Fibonacci
    A, b, counter = 0, 1, 0 while
    True:
        If counter > N: Return
        yield a
        A, B = B, a + b
        counter = 1
# f is an iterator that is returned by the generator
f = Fibonacci (a) while

True:
    try:
        prin T (next (f), end= "")
    except stopiteration:
        sys.exit ()
Def Fibonacci ():
    a=b=1
    yield a while
    True:
        a,b = b,a+b yield

        b

# F=fibonacci ()
# Print (Fibonacci ())
# f.__next__ ()
# f.__next__ () for Num in

Fibonacci ():
    if num > 100:
        break
    print (num)
    time.sleep (1)

Can debug look at the output, you understand.

There is also a way to define a builder: Builder expression "()"

My_generator = (x for x in range (3))
print (Type (my_generator)) for
i in My_generator:
    print (i)

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.