59

When I'm moving through a file with a csv.reader, how do I return to the top of the file. If I were doing it with a normal file I could just do something like "file.seek(0)". Is there anything like that for the csv module?

Thanks ahead of time ;)

Nope
  • 34,682
  • 42
  • 94
  • 119

3 Answers3

93

You can seek the file directly. For example:

>>> f = open("csv.txt")
>>> c = csv.reader(f)
>>> for row in c: print row
['1', '2', '3']
['4', '5', '6']
>>> f.seek(0)
>>> for row in c: print row   # again
['1', '2', '3']
['4', '5', '6']
Federico A. Ramponi
  • 46,145
  • 29
  • 109
  • 133
  • 4
    This does indeed start again, but if the file has a header row, it will return the column names as the "values" for the first row. So if you're using a DictReader, you'll get a row like this: "{'name': 'name', 'dob': 'dob', 'email': 'email}" – Nick K9 Dec 05 '16 at 22:19
  • 2
    Any way to do the same if you only have a reference to the reader and not the file handle? I am writing a function that takes a reader as input, scans through all the rows and (ideally) then resets the file location to seek(0) after parsing. Ideally, we would not have to pass the file parameter also to this function and the function signature would be simply: `csv_aggregate(reader, agg_functions, reset_after_calc=True)` Can we use `reader._file.seek(0)` or something similar? – aaronsteers Mar 05 '18 at 21:00
  • @Federico A. Ramponi How to seek to top if not using files. eg `csv_reader = csv.reader(stdout.decode('ascii').split('\n'), delimiter=' ')` – Ura Aug 24 '20 at 03:18
18

You can still use file.seek(0). For instance, look at the following:

import csv
file_handle = open("somefile.csv", "r")
reader = csv.reader(file_handle)
# Do stuff with reader
file_handle.seek(0)
# Do more stuff with reader as it is back at the beginning now

This should work since csv.reader is working with the same.

Evan Fosmark
  • 98,895
  • 36
  • 105
  • 117
  • 8
    althought the file_handle.seek(0) does work, the reader.line_num count does not get reset so if you want to use this later on then you'll have problems. you could of course repeat the 'reader = csv.reader(file_handle)' after the seek(0) but this then doesn't work properly if you have it within an outer 'for row in reader:' loop as 'reader.line_num' doesn't increment. If you replace the for loop with a while, that fixes that problem, but not quite sure what you do to tidy up the end-of-file situation on the last read. – jacanterbury May 29 '13 at 15:16
1

I've found the csv.reader and csv.DictReader a little difficult to work with because of the current line_num. making a list from the first read works well:

>>> import csv
>>> f = open('csv.txt')
>>> lines = list( csv.reader(f) ) # <-- list from csvReader
>>>
>>> for line in lines:
...  print(line)
['1', '2', '3']
['4', '5', '6']
>>>
>>> for line in lines:
...  print(line)
['1', '2', '3']
['4', '5', '6']
>>>
>>>lines[1]
['4', '5', '6']

this captures the optional first row used by the dictReader but lets you work with the list again and again and even inspect individual rows.

Marc Compere
  • 290
  • 4
  • 17