Iterators
This section makes a discussion of iterators. Only a special method----__iter__ is discussed, and this method is the basis of the iterator rules.
Iterator rules
Iteration means repeating things many times---just like you do in a loop. The __iter__ method returns an iterator that is the object that has the next method, and when the next method is called, the iterator returns its next value. If the next method is called, but the iterator has no value to return, a Stopiteration exception is thrown.
Here is an example of Gustav, using Iterators as follows:
Class Fibs: def __init__ (self): self.a = 0 self.b = 1 def next (self): self.a , self.b = self.b, self. A + self.b return SELF.A def __iter__ (self): return self>>> fibs = fibs () >>> for F in fibs: if f >: print F break #因为设置了break, so the loop stops here. 1597
Built-in function ITER can obtain iterators from objects that can be iterated.
>>> it = iter ([2]) >>> it.next () 1>>> it.next ()
Get a sequence from an iterator
In addition to iterating over iterators and iterative objects, you can convert them to sequences. An iterator can be used to replace most of the cases where the sequence can be used.
Class Testiterator: value = 0 def next (self): self.value + = 1 if self.value > 10:raise stopiteration< C4/>return self.value def __iter__ (self): return self>>> ti = testiterator () >>> list (TI) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Generator
Generators are also known as simple generators, and generators can help readers write very elegant code, but it is also possible to write any program without using a generator.
Creating generators
Creating a generator is as simple as creating a function.
>>> def flatten (nested): For sublist in nested: to element in sublist: yield element >> > nested = [[1,2],[3,4],[5]] #使用for循环 >>> for num in flatten (nested): print num 12345# or using the list function > >> list (Flatten (nested)) [1, 2, 3, 4, 5]
Recursive generators
The generator created above only handles two levels of nesting, and in order to handle nesting using two for loops, if you want to handle nesting of any layer? For example, you might need to add a for loop for each layer nesting, but you don't know how many layers are nested, so you have to make the solution more flexible and can now be solved with recursion.
>>> def FLA (aa): try: For BB in AA: for CC in FLA (BB): yield cc except TypeError: Yield aa>>> LIST (Fla ([[[[[1],2],3,4,[5,[6,7]],8])) #注意括号层次比较多 [1, 2, 3, 4, 5, 6, 7, 8]
When the FLA is called, there are two things: the basic situation and the case where recursion is required
In the basic case, the function is told to expand an element in which the for loop throws an TypeError exception that generates an element.
If you are expanding a list, you need special case handling. The program must traverse all the sub-lists and call the FLA on them.
-------------------
There is a problem with the above approach: if AA is a string-like object (String, Unicode, userstring, and so on), then it is a sequence and does not throw typeerror, but you do not want to iterate over such an object.
In order to handle this situation, you must add a check statement at the beginning of the generator. Try stitching the incoming object and a string to see if it will appear typeerror, which is the simplest and fastest way to check whether an object is similar to a string.
>>> def flatten (nested): try: #不要迭代类似字符串的对象 try:nested + ' except Typeerror:pass else : Raise TypeError for sublist in nested: for element in flatten (sublist): yield element except TypeError : yield nested >>> list (Flatten ([' foo ', [' Bar ', [' Baz ']])) [' foo ', ' Bar ', ' Baz ']
If Nested+ ' throws a typerror, it is ignored. If TypeError is not raised, the inner try statement throws a TypeError exception of its own.
Generator method
The new property of the generator is the ability to provide a value to the generator after it has started running. A channel for communication between the generator and the "Outside world":
* External scope access to the generator's send method, just like accessing the next method, except that the former uses a parameter (the "message" Sent---any object)
* Inside the generator is suspended, yield is now used as an expression instead of a statement, in other words, when the generator is newly run, the yield method returns a value, which is the value sent externally by the Send method. If the next method is used, then the yield method returns none.
Here's a simple example to illustrate this mechanism:
>>> def repeater (value): While True: new = (yield value) if new was not None:value = new >>& Gt R = Repeater >>> r.next () 42>>> r.send ("Hello, world!") ' Hello, world! '
Another two ways to build the generator:
* Throw method (called with exception type, with optional value and backtracking object) to throw an exception within the generator (in yield expression)
* The Close method (without parameters) is used to stop the generator.
Python Basic Learning Notes (11)