Question

I have a generator that generates a series, for example:

def triangleNums():
    '''generate series of triangle numbers'''
    tn = 0
    counter = 1
    while(True):
        tn = tn + counter
        yield tn
        counter = counter + 1

in python 2.6 I am able to make the following calls:

g = triangleNums() # get the generator
g.next()           # get next val

however in 3.0 if I execute the same two lines of code I'm getting the following error:

AttributeError: 'generator' object has no attribute 'next'

but, the loop iterator syntax does work in 3.0

for n in triangleNums():
    if not exitCond:
       doSomething...

I've not been able to find anything yet that explains this difference in behavior for 3.0.

Was it helpful?

Solution

Correct, g.next() has been renamed to g.__next__(). The reason for this is consistency: Special methods like __init__() and __del__ all have double underscores (or "dunder" in the current vernacular), and .next() was one of the few exceptions to that rule. This was fixed in Python 3.0. [*]

But instead of calling g.__next__(), as Paolo says, use next(g).

[*] There are other special attributes that have gotten this fix; func_name, is now __name__, etc.

OTHER TIPS

Try:

next(g)

Check out this neat table that shows the differences in syntax between 2 and 3 when it comes to this.

If your code must run under Python2 and Python3, use the 2to3 six library like this:

import six

six.next(g)  # on PY2K: 'g.next()' and onPY3K: 'next(g)'
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top