Reputation: 176
I know this has already been ask many ways, and I tried to read most of them, but still having trouble...
I have the nested dictionary
city = {'centerLatitude': '40',
'centerLongitude': '-86',
'listings': {'A Name Here': {'address': 'the address',
'city': 'acity',
'distance': 'AmillionMiles',
'facility_id': '1234',
'latitude': '34',
'longitude': '-86',
'price': 'tooMuch',
'rating': 'supergreat',
'size': "10'xAz'",
'state': 'XY',
'zip': '50505'}}}
I have this recursive python function (taken from another post)
def grab_children(father):
local_list = []
for key, value in father.iteritems():
local_list.append(key)
local_list.extend(grab_children(value))
return local_list
Calling the function with
print grab_children(city)
And I get this error... rather than a list
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
print grab_children(city)
File "<pyshell#5>", line 5, in grab_children
local_list.extend(grab_children(value))
File "<pyshell#5>", line 3, in grab_children
for key, value in father.iteritems():
AttributeError: 'str' object has no attribute 'iteritems'
From the error I thought that there was something going on with the value
used when the function calls itself again because it looks like it thinks it is a str which yes, has no .iteritems
, but running it in pieces and printing type(value)
it is always a dictionary (like it should be).
It works with this dictionary, also taken from another post, and I do not understand what is different about this dictionary.
city = {'<Part: 1.1>': {'<Part: 1.1.1>': {'<Part: 1.1.1.1>': {}},
'<Part: 1.1.2>': {}},
'<Part: 1.2>': {'<Part: 1.2.1>': {}, '<Part: 1.2.2>': {}},
'<Part: 1.3>': {}}
My questions are: Why am I getting this error? How do I over come the error? And if the error is caused by my dictionary being different, how is it different?
Upvotes: 0
Views: 4143
Reputation: 5658
your function should be changed to check if value is a dict, error
because you recursive function tries to run iteritems() on a value that isstring.
if isinstance(value,dict): clause need to be added to this recursive function.
Otherwise function eventually grabs a string..
change items() to iteritems() if not python 3
def grab_children(father):
local_list = []
for key, value in father.items():
local_list.append(key)
if isinstance(value,dict):
local_list.extend(grab_children(value))
return local_list
print(grab_children(city))
['centerLatitude', 'centerLongitude', 'listings', 'A Name Here', 'latitude', 'rating', 'zip', 'longitude', 'facility_id', 'size', 'city', 'distance', 'state', 'address', 'price']
Upvotes: 1
Reputation: 1622
You never put a stopping condition. The following retrieves all the keys in all the dictionaries:
def grab_children(father):
local_list = []
for key, value in father.iteritems():
local_list.append(key)
if type(value) is dict:
local_list.extend(grab_children(value))
return local_list
Upvotes: 0
Reputation: 1929
Notice in the sample that the "leaves" are all "{}". That is an empty dict. In your "city" your leaves are strings. To use this function as written, then instead of:
city = {'centerLatitude': '40'}
You would have to write:
city = { 'centerLatitude': { '40' : {} } }
etc.
But this question topic says "List of Lists" and that is not what your sample code does. Your sample code returns a single list. So I'm not really sure what you want as output.
Upvotes: 3