-4

I have a comma separated file listing the fifty states followed by cities in that state. The structure of the file is as follows:

Alabama, Alexander City, Decatur, Florence, Gadsden, Greenville, Guntersville, Huntsville,...
Arizona, Ajo, Avondale, Bisbee, Casa Grande, Chandler, Clifton,...
Arkansas, Arkadelphia, Arkansas, West Memphis,...
California, Alameda, Alhambra, Anaheim, Yorba Linda, Yuba City,...
...

The first item of each row is the state followed by the list of cities. The number of cities varies from state to state. I want to create a dictionary such that the state is the key who's value is the list of cities.

Here is my code:

import csv

# initialize an empty dictionary, and an empty list
my_dict = dict()
cities = list()

# read the csv file
with open('cities.csv', 'r') as csvfile:
    csvreader = csv.reader(csvfile)
    # process each row
    for row in csvreader:
        cities = row
        # pop the first item (state) off the list
        new_key = cities.pop(0)
        # store the key:value entry into the dictionary
        my_dict[new_key] = cities

# Print the results
print(my_dict)

I expected this: Results similar to a hash table.

{'Alabama' : ['Alexander City', 'Decatur', 'Florence', 'Gadsden', 'Greenville', 'Guntersville', 'Huntsville',]}
{'Arizona' : ['Ajo', 'Avondale', 'Bisbee', 'Casa Grande', 'Chandler', 'Clifton',]}
{'Arkansas' : ['Arkadelphia', 'Arkansas', 'West Memphis',]}
{'California' : ['Alameda', 'Alhambra', 'Anaheim', 'Yorba Linda', 'Yuba City',]}

but got this:

{'Alabama': [' Alexander City', ' Decatur', ' Florence', ' Gadsden', ' Greenville', ' Guntersville', ' Huntsville', ''], 'Arizona': [' Ajo', ' Avondale', ' Bisbee', ' Casa Grande', ' Chandler', ' Clifton', ''], 'Arkansas': [' Arkadelphia', ' Arkansas', ' West Memphis', ''], 'California': [' Alameda:', ' Alhambra', ' Anaheim', ' Yorba Linda', ' Yuba City', '']}

As you can see, I got one long row with the row having all the states and their associated cities. Maybe it is just the way I am printing it? Considering the actual csv file has up to 20 or more cities, some with 40 or more, for each state - the output is ridiculously long.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
  • likely duplicate of [this](https://stackoverflow.com/questions/6740918/creating-a-dictionary-from-a-csv-file) – futium Aug 16 '23 at 19:06
  • what do you mean "one long row"? There are no "rows". The result you *expected* doesn't isn't valid python source code, so it is really isn't clear what you are hoping for here. Note, the result you have is a `dict`, which **is a hash table**. – juanpa.arrivillaga Aug 16 '23 at 19:07
  • 3
    If you want to print the hash table that you created in some particular way, then you need to do that. Python also provide a pretty-printer, if you `from pprint import pprint` and want to use that. – juanpa.arrivillaga Aug 16 '23 at 19:08
  • Your expected output doesn't make any sense. That's not **a** dict, that's multiple dicts. You could do that if you wanted, but you'd need to put them *in* something, like a list. The actual output you're getting matches what you're describing. So what are you *actually* trying to accomplish here? Beware the [XY problem](//meta.stackexchange.com/q/66377/343832). – wjandrea Aug 16 '23 at 19:08
  • Import `pprint` using this import statement `from pprint import pprint` and use `pprint` to display `my_dict`. My guess is the dict is what you want, just the printing it out in line confuses [you](https://stackoverflow.com/users/3834254/user3834254). – Nikhil Devadiga Aug 16 '23 at 19:09
  • You really want the print to look like a bunch of dictionaries? Or perhaps something like `"Alabama: Alexander City, Decator, ..."`? – tdelaney Aug 16 '23 at 19:09
  • 1
    As an aside, if each line has a unique state, then this can be simplified to: `csvreader = csv.reader(csvfile)` and `my_dict = {state: cities for state, *cities in reader}`. Note, initializing an empty list in your original code was totally pointless – juanpa.arrivillaga Aug 16 '23 at 19:11
  • BTW, check out [ask], which has tips like how to write a good title and making a [mre]. – wjandrea Aug 16 '23 at 19:11
  • 1
    BTW, there's no point doing `cities = list()` when you're going to replace it with `cities = row`. Plus, putting it outside the loop makes it seem like it's going to persist, which is confusing. Also, you can just write `[]` instead of `list()` and `{}` instead of `dict()`. – wjandrea Aug 16 '23 at 19:16
  • 1
    And indeed you can just do `for cities in csvreader:` rather than `for row in csvreader: cities = row` – slothrop Aug 16 '23 at 19:19

2 Answers2

2

Its just the way you are printing it. When you print(my_dict), you get the single dictionary (AKA, hash table) you constructed. If you want to display in a different format, you can do it yourself. In your case, you seem to want to make each key/value pair in the dictionary look like its own dict. So, build and print.

for state, cities in my_dict.items():
    print({state: cities})

There are different ways to print. For instance

for state, cities in my_dict.items():
    print(f"{state}: {', '.join(cities)}")

Would print

Alabama: Alexander City, Decatur, Florence, ...

There are many options for display.

tdelaney
  • 73,364
  • 6
  • 83
  • 116
0

What you expect (or at least what you've written you expect) is not a dictionary but a set of them. In fact, what you posted as your "expected result" is one dictionary per row in CSV file.

Your code creates only one dictionary with a list assigned per key and that's exactly what you got.

If you want to create one dictionary per row item you need to create it inside the "for row" loop and print it before exiting it.

This code will lead to your expected output:

import csv

# initialize an empty dictionary, and an empty list
cities = list()

# read the csv file
with open('cities.csv', 'r') as csvfile:
    csvreader = csv.reader(csvfile)
    # process each row
    for row in csvreader:
        my_dict = dict()
        cities = row
        # pop the first item (state) off the list
        new_key = cities.pop(0)
        # store the key:value entry into the dictionary
        my_dict[new_key] = cities
        print(my_dict)

Note that the only difference is where the dictionary is defined and printed.

This is the output I've got:

{'Alabama': [' Alexander City', ' Decatur', ' Florence', ' Gadsden', ' Greenville', ' Guntersville', ' Huntsville']}

{'Arizona': [' Ajo', ' Avondale', ' Bisbee', ' Casa Grande', ' Chandler', ' Clifton']}

{'Arkansas': [' Arkadelphia', ' Arkansas', ' West Memphis']}

{'California': [' Alameda', ' Alhambra', ' Anaheim', ' Yorba Linda', ' Yuba City']}