1

I have a csv file with the following data:

name, postcode, meals
John, 27133, breakfast
Mary, 90356, lunch, supper
David, 95221, breakfast, lunch, supper

How could I read each row as a dictionary with the last field being a list:

d_john = {
    'name': 'John',
    'postcode': 27133,
    'meals': ['breakfast']
}

d_mary = {
    'name': 'Mary',
    'postcode': 90356,
    'meals': ['lunch', 'supper'],
}

d_david = {
    'name': 'David',
    'postcode': 95221,
    'meals': ['breakfast', 'lunch', 'supper']
}
0

1 Answer 1

1

Use:

# change data.csv to your file_path
with open("data.csv") as infile:
    next(infile)  # skip header
    for line in infile:
        name, postcode, *meals = line.strip().split(", ")
        print({"name": name, "postcode": postcode, "meals": meals})

Output

{'name': 'John', 'postcode': '27133', 'meals': ['breakfast']}
{'name': 'Mary', 'postcode': '90356', 'meals': ['lunch', 'supper']}
{'name': 'David', 'postcode': '95221', 'meals': ['breakfast', 'lunch', 'supper']}

The function next will move the iterator one line, effectively skipping the header. Then use extended iterable unpacking to read each value in the file, after using split for splitting.

A better alternative may be to use csv.DictReader:

import csv

# change data.csv to your file_path
with open("data.csv") as infile:
    reader = csv.DictReader(infile, fieldnames=["name", "postcode"], restkey="meals", skipinitialspace=True)
    next(reader)
    for row in reader:
        print(dict(row))

Output

{'name': 'John', 'postcode': '27133', 'meals': ['breakfast']}
{'name': 'Mary', 'postcode': '90356', 'meals': ['lunch', 'supper']}
{'name': 'David', 'postcode': '95221', 'meals': ['breakfast', 'lunch', 'supper']}

From the documentation (emphasis mine):

The fieldnames parameter is a sequence. If fieldnames is omitted, the values in the first row of file f will be used as the fieldnames. Regardless of how the fieldnames are determined, the dictionary preserves their original ordering.

If a row has more fields than fieldnames, the remaining data is put in a list and stored with the fieldname specified by restkey (which defaults to None).

The explanation of skipinitialspace=True, can be found in the Dialects and Formatting Parameters section, quoting for completeness:

When True, whitespace immediately following the delimiter is ignored. The default is False.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.