[Python-ideas] Adding __getter__ to compliment __iter__.

Terry Reedy tjreedy at udel.edu
Sun Jul 21 07:10:51 CEST 2013


On 7/21/2013 12:04 AM, Ron Adam wrote:

> The thing that got me on this is, if generators aren't faster than a
> class with method calls.

For the following generator function, iterator class pair, this is a 
radically wrong premise. (3.3.2)

def countgen(max):
     n = 0
     while n < max:
         yield n
         n += 1

class countit:
     def __iter__(self):
         return self
     def __init__(self, max):
         self.max = max
         self.n = 0
     def __next__(self):
         n = self.n
         if n < self.max:
             self.n = n+1
             return n
         else:
             raise StopIteration

print(list(countgen(100)) == list(countit(100)))

import timeit
print(timeit.repeat('for i in it: pass',
     "from __main__ import countgen; it = countgen(100)"))
print(timeit.repeat('for i in it: pass',
     "from __main__ import countit; it = countit(100)"))
 >>>
True
[0.055593401451847824, 0.047402394989421934, 0.04742083974032252]
[0.8787592707929215, 0.8775440691210892, 0.8786535208877584]

As the complexity of of the code in the loop or next method increases, 
the relative difference will go down, but should not disappear.

> Then why do we [use] generators?

In addition, the generator function is *much* easier to write than the 
equivalent iterator class because 1) it omits several lines of 
boilerplate (including attribute to local name and back) and 2) the loop 
body can yield the value exactly when it is available while the next 
method must end with the return.

I am not familiar with sending stuff to a 'generator' and how that 
affects timings. This is outside of the iterator protocol that 
generators were originally designed for.

-- 
Terry Jan Reedy



More information about the Python-ideas mailing list