3
\$\begingroup\$

I want to transform this dict to CSV:

{
  "California": ["San Fransisco", "Los Angeles","Oakland"],
  "Texas": ["Dallas", "Houston", "Austin"],
  "Florida": ["Miami", "Tampa"],
  ...
}

I want the following output:

California,San Fransisco
California,Los Angeles
California,Oakland
Texas,Dallas
Texas,Houston
Texas,Austin
Florida,Miami
Florida,Tampa

I wrote this code. This works well, but I wonder if there is a more pythonic way to do the same.

import csv

d = {
    "California": ["San Fransisco", "Los Angeles","Oakland"],
    "Texas": ["Dallas", "Houston", "Austin"],
    "Florida": ["Miami", "Tampa"]
}

with open("./out.csv", "w") as f:
  header = ["state", "city"]
  writer = csv.writer(f)
  writer.writerow(header)
  for i in d.keys():
    for j in d[i]:
      writer.writerow([i,j])
\$\endgroup\$
1
  • \$\begingroup\$ Btw, this sort of operation is maybe called going from jagged array (I would say wide data, but the rows aren't all the same length) to tall data. \$\endgroup\$ Commented Sep 9, 2022 at 5:30

2 Answers 2

9
\$\begingroup\$

As per PEP 8, the standard indentation for Python code is 4 spaces. Since whitespace is significant in Python, this is a pretty strong convention that you should follow.

The code itself isn't bad, but you could make it a bit more elegant using itertools.product() and csvwriter.writerows(). You can also use more meaningful variable names than i and j.

import itertools

with open("./out.csv", "w") as f:
    writer = csv.writer(f)
    writer.writerow(["state", "city"])
    for state, cities in d.items():
        writer.writerows(itertools.product([state], cities))
\$\endgroup\$
3
  • 4
    \$\begingroup\$ I also like that you've switched to d.items() instead of d.keys(). \$\endgroup\$ Commented Sep 8, 2022 at 14:22
  • 1
    \$\begingroup\$ That would be a more useful comment if you commented on the difference and why it's an improvement, @Teepeemm. \$\endgroup\$ Commented Sep 9, 2022 at 5:16
  • 1
    \$\begingroup\$ Using .item() is clearly better and more readable too, if you look at the original implementation (for j in d[i]:..). Plus, applying itertools instead of a loop is smart. \$\endgroup\$ Commented Sep 9, 2022 at 13:02
2
\$\begingroup\$

Flatten the dictionary into rows using clear variable names:

header = ["state", "city"]

rows = (
    [state, city]
    for state, cities in d.items()
    for city in cities
)

Then write those rows to a csv:

with open("./out.csv", "w") as f:
    writer = csv.writer(f)
    writer.writerow(header)
    writer.writerows(rows)
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.