Reputation: 51
I'm trying to retrieve an object that I've placed into a dictionary, but every time I try to retrieve it I receive an error:
class CSVEntry:
lat = []
lon = []
count = 0
# Create dictionary for tracking inputs
dict = defaultdict(list)
# Lookup the zipcode (returns an integer value)
zipcode = ConvertLatLonToZip(row[latCol], row[lonCol])
# If the zipcode is already in the dictionary, update it with the new count
if zipcode in dict:
oldEntry = dict[zipcode]
oldEntry.lat.append(row[latCol])
oldEntry.lon.append(row[lonCol])
oldEntry.count = dict[zipcode].count + 1
# Otherwise, make a new entry
else:
entry = CSVEntry()
entry.lat.append(row[latCol])
entry.lon.append(row[lonCol])
entry.count = 1
# Hash on the zipcode
dict[zipcode].append(entry)
It has no problem inserting entries into the dictionary, but as soon as it finds a duplicate, it fails with this error:
Traceback (most recent call last):
File "ParseCSV.py", line 125, in <module>
oldEntry.lat.append(row[latCol])
AttributeError: 'list' object has no attribute 'lat'
I apologize if this is a duplicate or a ridiculously simple question. I'm a beginner to Python and I searched for a long while before deciding to post.
EDIT: Added the definition of dict
Upvotes: 0
Views: 766
Reputation: 18633
Right now oldEntry
is a list
. It looks like you want to change
if zipcode in dict:
oldEntry = dict[zipcode]
oldEntry.lat.append(row[latCol])
oldEntry.lon.append(row[lonCol])
oldEntry.count = dict[zipcode].count + 1
to
if zipcode in dict:
oldEntry = dict[zipcode][0]
oldEntry.lat.append(row[latCol])
oldEntry.lon.append(row[lonCol])
oldEntry.count += 1
That being said, it might make more sense to simply create a new CSVEntry
object and append it to dict[zipcode]
Alternatively, you could make dict
a defaultdict
containing CSVEntry
objects, meaning that you wouldn't have to check whether zipcode was in dict. This would give you code like:
zip_dict = collections.defaultdict(CSVEntry)
zip_dict[zipcode].lat.append(row[latCol])
zip_dict[zipcode].lon.append(row[longCol])
zip_dict[zipcode].count += 1
This is likely the easiest way to solve your problem. On a sidenote, you want to avoid naming a variable dict
as that overwrites the builtin dict
type.
Upvotes: 2
Reputation: 2106
You made yourself a defaultdict containing lists. When you call dict[zipcode].append(entry)
, Python creates a new list and you insert your entry in that list. However, when you do oldEntry = dict[zipcode]
, you take that list and treat it as though it were a CSVEntry.
You should use a plain dict and insert your entries like so:
dict[zipcode] = entry
or append your item to the entry:
dict[zipcode].append(newEntry)
The point of a defaultdict
is to abstract away the search for existing items. If you make a defaultdict of lists, you should not look for the entry in your dictionary, but simply append new ones when necessary; the defaultdict will take care of giving you a new list to play with when you ask for a non-existing key.
Upvotes: 0