3

Using the function I wrote in Python 2, I was trying to concatenate csv files:

def concat_csv():
    """
    A function to concatenate the previously wrangled csv files in current working dir
    """
    with open('2017_oldnew.csv', 'a') as f_out:
        # First file
        with open('old.csv') as f_read:
            for line in f_read:
                f_out.write(line)
        # Second file
        with open('new.csv') as f_read:
            f_read.next()
            for line in f_read:
                f_out.write(line)

However, running this Python 3 gives me an error message:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-110-a5a430e1b905> in <module>()
      1 # Concatenate the files
----> 2 concat_csv()

<ipython-input-109-9a5ae77e9dd8> in concat_csv()
     10         # Second file
     11         with open('new.csv') as f_read:
---> 12             f_read.next()
     13             for line in f_read:
     14                 f_out.write(line)

AttributeError: '_io.TextIOWrapper' object has no attribute 'next'
George Liu
  • 3,601
  • 10
  • 43
  • 69

1 Answers1

4

It turns out that in Python 3, the syntax has changed. Instead of using next as a method, we need to use it as a function as below:

next(f_read)

which fixes the problem immediately.

George Liu
  • 3,601
  • 10
  • 43
  • 69
  • More specifically, an iterator has a method called `__next__`, not `next`, that is called when the iterator is passed to the `next` function. This brings it in line with other protocols (e.g. `len` calling `__len__`, etc). – chepner Mar 28 '17 at 21:42
  • Note: [The `next` function exists in 2.6 and higher](https://docs.python.org/2/library/functions.html#next), so you can use this code on both 2.6+ and 3.x. The actual change from 2 to 3 was that the special method's name changed from `next` to `__next__` (to match other special methods, and avoid causing problems if `next` made sense as a method but your class wasn't an iterator). Using the `next` function papers over that change; it works correctly on both versions. – ShadowRanger Mar 28 '17 at 21:44