From the documentation of csv, the first argument to csv.reader or csv.DictReader is csvfile -
csvfile can be any object which supports the iterator protocol and returns a string each time its
__next__()method is called — file objects and list objects are both suitable.
In your case when you give the string as the direct input for the csv.DictReader() , the __next__() call on that string only provides a single character, and hence that becomes the header, and then __next__() is continuously called to get each row.
Hence, you need to either provide an in-memory stream of strings using io.StringIO:
>>> import csv
>>> s = """a,b,c
... 1,2,3
... 4,5,6
... 7,8,9"""
>>> import io
>>> reader_list = csv.DictReader(io.StringIO(s))
>>> print(reader_list.fieldnames)
['a', 'b', 'c']
>>> for row in reader_list:
... print(row)
...
{'a': '1', 'b': '2', 'c': '3'}
{'a': '4', 'b': '5', 'c': '6'}
{'a': '7', 'b': '8', 'c': '9'}
or a list of lines using str.splitlines:
>>> reader_list = csv.DictReader(s.splitlines())
>>> print(reader_list.fieldnames)
['a', 'b', 'c']
>>> for row in reader_list:
... print(row)
...
{'a': '1', 'b': '2', 'c': '3'}
{'a': '4', 'b': '5', 'c': '6'}
{'a': '7', 'b': '8', 'c': '9'}
Answer from Anand S Kumar on Stack Overflowpython - understanding csv DictReader, what it returns? - Stack Overflow
When using reader or DictReader from the csv module, why do you need to access the return value while the file is still open?
What does .dictreader() do?
csv.DictReader marked as producing Dict[str, str] but can have a None key
Videos
The csv.DictReader function expects a file object as its first argument, not a string. So, it always is used with normal file io.
for example,
with open('input.csv', 'r') as f:
reader = csv.DictReader(f, delimiter=' ', fieldnames = ['Device', 'tps', 'kB_read/s' ,'kB_wrtn/s', 'kB_dscd/s', 'kB_read', 'kB_wrtn', 'kB_dscd'])
And, you can iterate the reader (i.e., iterable of dicts) row by row.
for row in reader:
print(row)
The row variable contains dictionary-like object that you can easily access by key, for example, row['Device'].
The csv module expects the input to be an iterable containing lines of the CSV. ' '.join(ios_r.stdout.split()) is returning a single string (it simply collapses all the whitespace delimiters into single spaces). Iterating over a string returns loops over the characters, not the lines.
You should perform the join and split on each line, not the entire stdout at once.
ios_e = csv.DictReader(' '.join(line.split()) for line in ios_r.stdout, delimiter = ' ')
You won't need the fieldnames argument in this code, since it will get them from the first line.
Ok, this will make more sense. Why does this work:
import csv
with open('test.csv') as csv_file:
csv_reader = csv.DictReader(csv_file)
for row in csv_reader:
print(row)But this gives an error that the file is closed:
import csv
with open('test.csv') as csv_file:
csv_reader = csv.DictReader(csv_file)
for row in csv_reader:
print(row)
Traceback (most recent call last): File "c:\Users\John\Documents\Python\test_project\test2.py", line 5, in <module> for row in csv_reader: File "C:\Users\John\AppData\Local\Programs\Python\Python311\Lib\csv.py", line 110, in next self.fieldnames File "C:\Users\John\AppData\Local\Programs\Python\Python311\Lib\csv.py", line 97, in fieldnames self._fieldnames = next(self.reader) ^ ValueError: I/O operation on closed file.
Does DictReader (and also reader) not just run once and return a value? Why is csv_file being accessed after the line it's used in?
Thanks!
import csv
reader = csv.DictReader(open('myfile.csv'))
for row in reader:
# profit !
Use csv.DictReader:
Create an object which operates like a regular reader but maps the information read into a dict whose keys are given by the optional fieldnames parameter. The fieldnames parameter is a
sequencewhose elements are associated with the fields of the input data in order. These elements become the keys of the resulting dictionary. If the fieldnames parameter is omitted, the values in the first row of the csvfile will be used as the fieldnames. If the row read has more fields than the fieldnames sequence, the remaining data is added as a sequence keyed by the value of restkey. If the row read has fewer fields than the fieldnames sequence, the remaining keys take the value of the optional restval parameter. Any other optional or keyword arguments are passed to the underlyingreaderinstance...