0

Started learning python after lots of ruby experience. With that context in mind:

I have a csv file that looks something like this:

city_names.csv

"abidjan","addis_ababa","adelaide","ahmedabad"

With the following python script I'd like to read this into a list:

city_names_reader.py

import csv

city_name_file = r"./city_names.csv"

with open(city_name_file, 'rb') as file:
  reader = csv.reader(file)
  city_name_list = list(reader)

print city_name_list

The result surprised me: [['abidjan', 'addis_ababa', 'adelaide', 'ahmedabad']]

Any idea why I'm getting a nested list rather than a 4-element list? I must be overlooking something self-evident.

2
  • try: city_name_list = [row for row in reader] Commented Nov 30, 2016 at 13:06
  • 2
    Each line of the file is a list of values. Your list() call creates a list of lists, one for each line. Commented Nov 30, 2016 at 13:06

3 Answers 3

3

A CSV file represents a table of data. A table contains both columns and rows, like a spreadsheet. Each line in a CSV file is one row in the table. One row contains multiple columns, separated by ,

When you read a CSV file you get a list of rows. Each row is a list of columns.

If your file have only one row you can easily just read that row from the list:

city_name_list = city_name_list[0]

Usually each column represent some kind of data (think "column of email addresses"). Each row then represent a different object (think "one object per row, each row can have one email address"). You add more objects to the table by adding more rows.

It is not common with wide tables. Wide tables are those that grow by adding more columns instead of rows. In your case you have only one kind of data: city names. So you should have one column ("name"), with one row per city. To get city names from your file you could then read the first element from each row:

city_name_list = [row[0] for row in city_name_list]

In both cases you can flatten the list by using itertools.chain:

city_name_list = itertools.chain(city_name_list)
Sign up to request clarification or add additional context in comments.

4 Comments

That works for me, yes, but is this the most idiomatic way to go about things? In other words, if I know that my csv file will just be one comma-separated list, is there a way I can read it in without creating the unnecessary nested structure in the first place?
Depends on your definition of "idiomatic". This is an idiomatic way of working with CSV files. But your file is not an idiomatic CSV (edited my answer to clarify that) so perhaps you shouldn't use a CSV parser in the first place!
@pgblu: You can use next(reader), but do take a look at Emil's edited post.
Re: not using a CSV parser, what would I use instead? I just want to take a file with a comma-separated list and read it into a list for further processing. I did not realize that the 'normative' CSV is akin to a table. Makes me think the term 'CSV' is a misnomer, but that's a separate topic.
2

As others suggest, your file is not an idiomatic CSV file. You can simply do:

with open(city_name_file, "rb") as fp:
    city_names_list = fp.read().split(",")

Comments

0

Based on comments, here is a possible solution:

import csv

city_name_file = r"./city_names.csv"
city_name_list = []

with open(city_name_file, 'rb') as file:
  reader = csv.reader(file)
  for item in reader:
    city_name_list += item

print city_name_list

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.