289

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

def triangle_nums():
    '''Generates a series of triangle numbers'''
    tn = 0
    counter = 1
    while True:
        tn += counter
        yield tn
        counter += + 1

In Python 2 I am able to make the following calls:

g = triangle_nums()  # get the generator
g.next()             # get the next value

however in Python 3 if I execute the same two lines of code I get the following error:

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

but, the loop iterator syntax does work in Python 3

for n in triangle_nums():
    if not exit_cond:
       do_something()...

I haven't been able to find anything yet that explains this difference in behavior for Python 3.

3 Answers 3

476

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__(), use next(g).

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

8
  • any idea why python 2 eschewed the dunder convention for these methods in the first place?
    – Rick
    Commented Mar 29, 2016 at 14:47
  • That's probably just an oversight. Commented Mar 31, 2016 at 11:49
  • What about when you overwrite __ str __ in classes? Does it change str(obj) or __str__(obj) ?
    – NoName
    Commented Oct 27, 2019 at 4:00
  • 1
    @NoName Yes, you do. Commented Oct 30, 2019 at 9:56
  • 1
    @MatthewMilone It's mentioned in the PEP where the change was proposed, which was five years later. python.org/dev/peps/pep-3114 Commented Oct 8, 2020 at 16:56
158

Try:

next(g)

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

4
  • 1
    @MaikuMori I fixed the link (waiting for peer revision) (The site diveintopython3.org seems to be down. Mirror site diveintopython3.ep.io is still alive)
    – gecco
    Commented Jan 5, 2012 at 20:59
  • 1
    Fixed the link again. python3porting.com/differences.html is more complete, btw. Commented Jul 27, 2013 at 3:53
  • Is there any justification for the switch from a method to a function, beyond g.next() should really be g.__next__(), and we need to have something that isn't a dunder method with the functionality of g.next()? Commented Dec 17, 2019 at 23:25
  • Works for the error ` 'generator' object has no attribute 'next' `.
    – Yugendran
    Commented Apr 13, 2021 at 11:51
12

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)'
1
  • 18
    There's not much need for this unless you need to support Python versions earlier than 2.6. Python 2.6 and 2.7 have the next built-in function. Commented Sep 17, 2015 at 17:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.