Python – Distinguish between nested dictionary assignments and list value access in Python dictionaries

Distinguish between nested dictionary assignments and list value access in Python dictionaries… here is a solution to the problem.

Distinguish between nested dictionary assignments and list value access in Python dictionaries

I have the dictionary “body” for the body part and its corresponding bounding boxes (xmin, ymin, xmax, ymax):

body = {'lHand': [872, 1075, 920, 1194], 'lfoot': [831, 1665, 928, 1777], 
        'rfoot': [676, 1624, 741, 1743], 'rKnee': [657, 1313, 726, 1372], 
        'Lshoul': [809, 678, 885, 740], 'face': [698, 494, 816, 652], 
        'Lknee': [797, 1323, 862, 1395], 'rShoul': [608, 674, 690, 737], 
        'rHand': [563, 1074, 620, 1184], 'hips': [641, 977, 848, 1019]}

I want to replace each list value in this dictionary with a nested dictionary where the list element for each key is itself marked: xmin, ymin, xmax, and ymax, respectively. The goal will be this

body['part']['coordinate'] = value

Like

body['face']['xmin'] = 698

For this, I wrote the following:

for (part, bounding_box) in body.items():
    for (coordinate, value) in zip(['xmin', 'ymin', 'xmax', 'ymax'], bounding_box):
        # the (non-functional) assignment 
        body[part][coordinate] = value
    body[part]['center'] = center(part)
    # joints are centers of body parts
    joint[part] = body[part]['center']

The error I get,

<pre class=”lang-sh prettyprint-override”>File "body.py", line 110, in <module>
body[part][coordinate] = value
TypeError: list indices must be integers, not str

Makes me feel like Python is reading my attempt to create nested dictionary elements, thinking of it as an attempt to access one of the list members associated with the key “section”.

How do I distinguish between the two operations?

Thanks!

Solution

Yes, the problem with your approach is:

body[part][coordinate] = value

body[part] returns the list, and then you try to index the list using the string coordinate, but it fails.

You can just use the dictionary to understand:

>>> labels = ['xmin', 'ymin', 'xmax', 'ymax']
>>> new_body = {k:dict(zip(labels, v)) for k,v in body.items()}
>>> pprint(new_body)
{'Lknee': {'xmax': 862, 'xmin': 797, 'ymax': 1395, 'ymin': 1323},
 'Lshoul': {'xmax': 885, 'xmin': 809, 'ymax': 740, 'ymin': 678},
 'face': {'xmax': 816, 'xmin': 698, 'ymax': 652, 'ymin': 494},
 'hips': {'xmax': 848, 'xmin': 641, 'ymax': 1019, 'ymin': 977},
 'lHand': {'xmax': 920, 'xmin': 872, 'ymax': 1194, 'ymin': 1075},
 'lfoot': {'xmax': 928, 'xmin': 831, 'ymax': 1777, 'ymin': 1665},
 'rHand': {'xmax': 620, 'xmin': 563, 'ymax': 1184, 'ymin': 1074},
 'rKnee': {'xmax': 726, 'xmin': 657, 'ymax': 1372, 'ymin': 1313},
 'rShoul': {'xmax': 690, 'xmin': 608, 'ymax': 737, 'ymin': 674},
 'rfoot': {'xmax': 741, 'xmin': 676, 'ymax': 1743, 'ymin': 1624}}
>>>

As you wish:

>>> new_body['face']['xmin']
698
>>>

Of course, understanding the structure can be replaced by a for loop:

>>> new_body = {}
>>> for k, v in body.items():
...     new_body[k] = dict(zip(labels, v))
...
>>> pprint(new_body)
{'Lknee': {'xmax': 862, 'xmin': 797, 'ymax': 1395, 'ymin': 1323},
 'Lshoul': {'xmax': 885, 'xmin': 809, 'ymax': 740, 'ymin': 678},
 'face': {'xmax': 816, 'xmin': 698, 'ymax': 652, 'ymin': 494},
 'hips': {'xmax': 848, 'xmin': 641, 'ymax': 1019, 'ymin': 977},
 'lHand': {'xmax': 920, 'xmin': 872, 'ymax': 1194, 'ymin': 1075},
 'lfoot': {'xmax': 928, 'xmin': 831, 'ymax': 1777, 'ymin': 1665},
 'rHand': {'xmax': 620, 'xmin': 563, 'ymax': 1184, 'ymin': 1074},
 'rKnee': {'xmax': 726, 'xmin': 657, 'ymax': 1372, 'ymin': 1313},
 'rShoul': {'xmax': 690, 'xmin': 608, 'ymax': 737, 'ymin': 674},
 'rfoot': {'xmax': 741, 'xmin': 676, 'ymax': 1743, 'ymin': 1624}}
>>>

I think by reading your code, you’re trying to “take the long term” like this :

>>> new_body = {}
>>> for k, v in body.items():
...     new_body[k] = {}
...     for coordinate, value in zip(labels, v):
...         new_body[k][coordinate] = value
...
>>> pprint(new_body)
{'Lknee': {'xmax': 862, 'xmin': 797, 'ymax': 1395, 'ymin': 1323},
 'Lshoul': {'xmax': 885, 'xmin': 809, 'ymax': 740, 'ymin': 678},
 'face': {'xmax': 816, 'xmin': 698, 'ymax': 652, 'ymin': 494},
 'hips': {'xmax': 848, 'xmin': 641, 'ymax': 1019, 'ymin': 977},
 'lHand': {'xmax': 920, 'xmin': 872, 'ymax': 1194, 'ymin': 1075},
 'lfoot': {'xmax': 928, 'xmin': 831, 'ymax': 1777, 'ymin': 1665},
 'rHand': {'xmax': 620, 'xmin': 563, 'ymax': 1184, 'ymin': 1074},
 'rKnee': {'xmax': 726, 'xmin': 657, 'ymax': 1372, 'ymin': 1313},
 'rShoul': {'xmax': 690, 'xmin': 608, 'ymax': 737, 'ymin': 674},
 'rfoot': {'xmax': 741, 'xmin': 676, 'ymax': 1743, 'ymin': 1624}}
>>>

Related Problems and Solutions