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.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.
Python csv.DictReader - Stack Overflow
What does .dictreader() do?
Using Python's csv.dictreader to search for specific key to then print its value - 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?
The documentation you linked to provides half the answer:
class
csv.DictReader(csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)[...] maps the information read into a dict whose keys are given by the optional fieldnames parameter. If the fieldnames parameter is omitted, the values in the first row of the csvfile will be used as the fieldnames.
It would seem that if the fieldnames parameter is passed, the given file will not have its first record interpreted as headers (the parameter will be used instead).
# file_data is the text of the file, not the filename
reader = csv.DictReader(file_data, ("title", "value"))
for i in reader:
list_of_stuff.append(i)
which will (apparently; I've been having trouble with it) produce the following data structure:
[{"title": "Mamer", "value": "285713:13"},
{"title": "Champhol", "value": "461034:2"},
{"title": "Station Palais", "value": "972811:0"}]
which may need to be further massaged into a title-to-value mapping by something like this:
data = {}
for i in list_of_stuff:
data[i["title"]] = i["value"]
Now just use the keys and values of data to complete your task.
And here it is as a dictionary comprehension:
data = {row["title"]: row["value"] for row in csv.DictReader(file_data, ("title", "value"))}
The currently accepted answer is fine, but there's a slightly more direct way of getting at the data. The dict() constructor in Python can take any iterable.
In addition, your code might have issues on Python 3, because Python 3's csv module expects the file to be opened in text mode, not binary mode. You can make your code compatible with 2 and 3 by using io.open instead of open.
import csv
import io
with io.open('anchor_summary2.csv', 'r', newline='', encoding='utf-8') as f:
data = dict(csv.reader(f))
print(data['Champhol'])
As a warning, if your csv file has two rows with the same value in the first column, the later value will overwrite the earlier value. (This is also true of the other posted solution.)
If your program really is only supposed to print the result, there's really no reason to build a keyed dictionary.
import csv
import io
# Python 2/3 compat
try:
input = raw_input
except NameError:
pass
def main():
# Case-insensitive & leading/trailing whitespace insensitive
user_city = input('Enter a city: ').strip().lower()
with io.open('anchor_summary2.csv', 'r', newline='', encoding='utf-8') as f:
for city, value in csv.reader(f):
if user_city == city.lower():
print(value)
break
else:
print("City not found.")
if __name __ == '__main__':
main()
The advantage of this technique is that the csv isn't loaded into memory and the data is only iterated over once. I also added a little code the calls lower on both the keys to make the match case-insensitive. Another advantage is if the city the user requests is near the top of the file, it returns almost immediately and stops looking through the file.
With all that said, if searching performance is your primary consideration, you should consider storing the data in a database.
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!