0

I have a csv file, with simply looks like this:

CSV File

I have the following code, which reads the csv file, and then can then print/ access information in the CSV file.

import csv

class CsvReader:
    
    with open("Items.csv") as fp:
        reader = csv.reader(fp, delimiter=",", quotechar='"')
        next(reader, None)  # skip the headers
        data_read = [row for row in reader]

    print(data_read[0])

I get this as the output from the print

['1', '5.99$, '1', 'Blueberry Muffin']

How would I format this into a dictionary, with the headers as the keys and the information as the elements?

For example, the code would output:

{Item #: 1, Price: 5.99, Quantity: 1, Name: Blueberry Muffin}

I referenced and saw a lot of similarities in this post: How do I read and write CSV files with Python?

but couldnt find any more specifics on how to format the output specifically this way, without using something such as pandas, which I am not looking to use.

  • Use the `zip()` function to make the header as a key and the things below it as value. Loop through each value and zip it with the header until you zip all of them. – ss3387 Sep 05 '22 at 17:49
  • Do not use images for textual data. Copy and paste the CSV content as text as update to question. As of now know can use that data without transcribing from the image. – Adrian Klaver Sep 05 '22 at 17:58
  • From [csv](https://docs.python.org/3/library/csv.html#module-csv) use `DictReader` as `reader = csv.DictReader(fp, delimiter=",", quotechar='"')`. This assumes the header row you skipped has `Item #, Price, Quantity, Name`. Otherwise you will to add `fieldnames=[Item #, Price, Quantity, Name]`. – Adrian Klaver Sep 05 '22 at 17:59

3 Answers3

3

If you want dict keys as fields i.e columns then why are you skipping them. Here the easy solution.

import csv

class CsvReader:
    with open("Item.csv") as fp:
        reader = csv.reader(fp, delimiter=",", quotechar='"')
        fields = next(reader)
        data_read = []
        for row in reader:
            data_read.append(dict(zip(fields, row)))

    print(data_read[0])

First store the column names and map them with each row element.

Harsh Narwariya
  • 498
  • 2
  • 11
0

There's a couple ways to do this... And I agree that using Pandas is likely overkill for reading simple files. You could argue that even using csv_reader is overkill. :)

Anyhow, here are 3 variations. All you need to do is capture the labels and use them as the keys in the dictionary. Realize that the methods below will get you a "list of dictionaries" (or "records" type format in pandas-speak). An alternative would be a "dictionary of dictionaries" using the item number as the first key, but in essence that is the same as a list index...so about the same. You could also probably forgo capturing the item number as that is just the index in the resultant list of dicts, but that is nuance.

You might also be interested in capturing them in a named tuple which is shown in the last variant. Very easy to work with...

# Grocery Reader

import csv
from collections import namedtuple


with open("data.csv") as fp:
    reader = csv.reader(fp, delimiter=",", quotechar='"')
    labels = next(reader, None)  # capture the headers
    result = []
    for row in reader:  # iterate the remaining rows
        pairs = zip(labels, row)
        result.append(dict(pairs))

print(result)

# the above isn't real satisfying as the numeric objects are captured as strings.
# so...
with open("data.csv") as fp:
    reader = csv.reader(fp, delimiter=",", quotechar='"')
    labels = next(reader, None)  # capture the headers
    result = []
    for row in reader:  # iterate the remaining rows
        row[0] = int(row[0])
        row[1] = float(row[1])
        row[2] = int(row[2])
        pairs = zip(labels, row)
        result.append(dict(pairs))

print(result)

with open("data.csv") as fp:
    reader = csv.reader(fp, delimiter=",", quotechar='"')
    labels = next(reader, None)  # capture the headers
    # make lowercase...just for standardization
    labels = [t.lower() for t in labels]
    Grocery = namedtuple('Grocery', labels)
    result = []
    for row in reader:  # iterate the remaining rows
        row[0] = int(row[0])
        row[1] = float(row[1])
        row[2] = int(row[2])
        grocery = Grocery(*row)
        result.append(grocery)

for grocery in result:
    # the below presumes you know the names inside the named tuple...
    print(f'a {grocery.name} costs {grocery.price}')

Yields (data.csv can be inferred)

[{'Item': '1', 'Price': '4.99', 'Qty': '2', 'Name': 'Muffin'}, {'Item': '2', 'Price': '1.25', 'Qty': '6', 'Name': 'Gum'}, {'Item': '3', 'Price': '2.50', 'Qty': '8', 'Name': 'Cookie'}]
[{'Item': 1, 'Price': 4.99, 'Qty': 2, 'Name': 'Muffin'}, {'Item': 2, 'Price': 1.25, 'Qty': 6, 'Name': 'Gum'}, {'Item': 3, 'Price': 2.5, 'Qty': 8, 'Name': 'Cookie'}]
a Muffin costs 4.99
a Gum costs 1.25
a Cookie costs 2.5
AirSquid
  • 10,214
  • 2
  • 7
  • 31
  • This is amazing! Thank you so much for the beautiful and several answer response. Is there any reason why the second option wouldn't work in a class sense? When I use the code out of a class, It seems to work, but when I put it in a class, and indent it appropriately, the interpreter tells me "result is not defined" when I try to print it, even though I have result = [ ] – Fear_Schwier Sep 05 '22 at 18:09
  • This is the long way to do what `DictReader` from here [csv](https://docs.python.org/3/library/csv.html#module-csv) does out of the box. – Adrian Klaver Sep 05 '22 at 18:25
  • It isn't real clear how you have your Class implementation set up (or why you are doing that), but if you are trying to access `result` from outside the class, you probably need to make it a class variable like `self.class`, but it all depends on how your class is set up. If you are stuck, get a small example set up and post another question... You'll get quick feedback on that type of issue. – AirSquid Sep 05 '22 at 18:27
0

Use DictReader from here csv.

cat food.csv                                                                                                                                                                                                           
Item #,Price,Quantity,Name
1, 5.99$,1,Blueberry Muffin


import csv
with open('food.csv') as csv_file:
    reader = csv.DictReader(csv_file,delimiter=",", quotechar='"')
    for row in reader:
        print(dict(row))

{'Item #': '1', 'Price': ' 5.99$', 'Quantity': '1', 'Name': 'Blueberry Muffin'}

Adrian Klaver
  • 15,886
  • 2
  • 17
  • 28