区分嵌套字典分配与Python字典中的列表值访问

时间:2017-03-20 21:21:48

标签: python dictionary

我有字典``body''身体部位及其相应的边界框形式(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]}

我希望用嵌套字典替换此字典中的每个列表值,其中每个键的列表元素本身都标记为:分别为xmin,ymin,xmax和ymax。目标就像是

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

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

为此,我写了以下内容:

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']

我得到的错误,

File "body.py", line 110, in <module>
    body[part][coordinate] = value
TypeError: list indices must be integers, not str

让我觉得Python正在阅读我创建嵌套字典元素的尝试,试图访问与关键字&#39;部分相关联的列表中的一个成员。

如何区分这两项操作?

谢谢!

1 个答案:

答案 0 :(得分:3)

是的,您的方法存在的问题是:

body[part][coordinate] = value

body[part]返回列表,然后您尝试使用字符串coordinate索引列表,然后失败。

你可以使用词典理解:

>>> 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}}
>>>

如你所愿:

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

当然,理解构造可以用for循环替换:

>>> 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}}
>>>

我认为,通过阅读你的代码,你试图“走很长的路”,就像这样:

>>> 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}}
>>>