我有一个类似的数据列表
data = [
{
"name": "Box 0",
"type": "Box",
"vals": {
"corner1": "0,0,0",
"corner2": "0,0,5",
"rotate": "0",
"scale": "1",
"translate": "0,0,0"
}
},
{
"name": "Ovus 1",
"type": "Ovus",
"vals": {
"radiusb": "1",
"radiust": "0.5",
"rotate": "0",
"scale": "1",
"translate": "0,0,0"
}
}
]
我想创建一个表单的函数
fetch_attributes(name, key)
其中我可以给出关键属性值类型、vals或scale。
我的问题是scale属性在vals字典中。我能让函数在我给出key=type时给我类型吗?当我要求key=scale,它会自动进入vals字典。
我的方法
我使用此代码作为name="Box 0"的示例
obj = [i for i in data if i['name'] == name][0]
key_1 = "['vals']" # If I want complete dict of vals
key_2 = "['vals']['scale']" #If I want only one val out of vals
key_3 = "['type']" # If I want type
result_1 = eval('obj' + key_1)
result_2 = eval('obj' + key_2)
result_3 = eval('obj' + key_3)
我想知道是否有更好或更像蟒蛇的方式来完成这项任务
编辑
我想要一种方法,它也将帮助或指导创建一个edit_attributes函数作为
edit_attributes(name, key, value)
我认为这(现在(符合您的要求:
def fetch_attributes(data, name, key):
for dct in data:
if dct['name'] == name:
obj = dct
break
else:
raise KeyError(f'No object with name {name!r} in data')
if isinstance(obj, dict):
if key in obj:
return obj[key]
for value in obj.values():
if isinstance(value, dict): # Nested dict?
if key in value:
return value[key]
raise KeyError(f'{key!r} not in data')
print(fetch_attributes(data, 'Box 0', 'vals')) # -> {'corner1': '0,0,0', 'corner2': '0,0,5', 'rotate': '0', 'scale': '1', 'translate': '0,0,0'}
print(fetch_attributes(data, 'Box 0', 'scale')) # -> 1
print(fetch_attributes(data, 'Box 0', 'type')) # -> Box
这应该适用于任何级别的字典嵌套。
def find(obj, key):
if key not in obj:
for k in obj.keys():
if type(obj[k]) == type({}):
return find(obj[k], key)
else:
return obj[key]
return None
def fetch_attributes(name, key):
obj = [i for i in data if i['name'] == name][0]
return find(obj, key)
但是,如果obj = [i for i in data if i['name'] == name][0]
返回多个值,那么您也需要一个for
循环。
当找不到属性名称时,可以利用字典的get((函数的第二个参数级联到子字典中:
def getProp(d,key): return d.get(key,d["vals"].get(key,None))
输出:
for d in data:
print([ getProp(d,"name"),getProp(d,"type"),getProp(d,"scale") ])
# ['Box 0', 'Box', '1']
# ['Ovus 1', 'Ovus', '1']
赋值会稍微复杂一些,但也可以使用setdefault((:
def setProp(d,key,value):
[d,d.setdefault("vals",dict())][key=="vals"][key] = value