我正在使用嵌套字典,并且我试图弄清楚如何有效地修改某些嵌套和非嵌套键/值。简而言之,我试图做到以下几点:
这是我正在使用的字典的基本示例:
pet_dictionary = {'Buford':{'color':'white', 'weight': 95, 'age':'3',
'breed':'bulldog'},
'Henley':{'color':'blue', 'weight': 70, 'age':'2',
'breed':'bulldog'},
'Emi':{'color':'lilac', 'weight': 65, 'age':'1',
'breed':'bulldog'},
}
我想取非嵌套键,即每只狗的名字(即Buford,Henley,Emi),用年龄的嵌套值切换它(即3,2,1),然后更改嵌套来自' age'的关键名称名字。'所以输出应该如下所示:
pet_dictionary = {'3':{'color':'white', 'weight': 95, 'name':'Buford',
'breed':'bulldog'},
'2':{'color':'blue', 'weight': 70, 'name':'Henley',
'breed':'bulldog'},
'1':{'color':'lilac', 'weight': 65, 'name':'Emi',
'breed':'bulldog'},
}
我了解如何逐个手动执行此操作,但我不确定以更优雅/最佳方式进行所有这些更改的最佳方法是什么。
答案 0 :(得分:2)
这可能会有所帮助
pet_dictionary = {'Buford':{'color':'white', 'weight': 95, 'age':'3',
'breed':'bulldog'},
'Henley':{'color':'blue', 'weight': 70, 'age':'2',
'breed':'bulldog'},
'Emi':{'color':'lilac', 'weight': 65, 'age':'1',
'breed':'bulldog'},
}
d = {}
for k,v in pet_dictionary.items():
d[v['age']] = pet_dictionary[k]
d[v['age']].update({"name": k})
del d[v['age']]['age']
print d
<强>输出强>:
{'1': {'color': 'lilac', 'breed': 'bulldog', 'name': 'Emi', 'weight': 65}, '3': {'color': 'white', 'breed': 'bulldog', 'name': 'Buford', 'weight': 95}, '2': {'color': 'blue', 'breed': 'bulldog', 'name': 'Henley', 'weight': 70}}
答案 1 :(得分:2)
在迭代字典时,您可以分三步干净地构建新字典:
# Preserves original dict
d = {}
for k, v in pet_dictionary.items():
key = v["age"] # 1. grab the new key
d[key] = {"name": k} # 2. add new "name" item
d[key].update({k_:v_ for k_, v_ in v.items() if k_!="age"}) # 3. update the new dict
d
答案 2 :(得分:2)
这是pythons iterables闪耀的情况
p = {'Buford':{'color':'white', 'weight': 95, 'age':'3',
'breed':'bulldog'},
'Henley':{'color':'blue', 'weight': 70, 'age':'2',
'breed':'bulldog'},
'Emi':{'color':'lilac', 'weight': 65, 'age':'1',
'breed':'bulldog'},
}
new_dictionary = {p[i]['age']:{'color':p[i]['color'],'weight':p[i]['weight'],
'name':i,'breed':p[i]['breed']} for i in p}
<强>输出:强>
{'3': {'color': 'white', 'weight': 95, 'name': 'Buford', 'breed': 'bulldog'},
'2': {'color': 'blue', 'weight': 70, 'name': 'Henley', 'breed': 'bulldog'},
'1': {'color': 'lilac', 'weight': 65, 'name': 'Emi', 'breed': 'bulldog'}}
答案 3 :(得分:1)
def flip(k, v):
v1 = dict(v)
v1.update(name=k)
return v1.pop('age'), v1
pet_dictionary2 = dict([flip(k, v) for k, v in pet_dictionary.items()])
# import pprint as pp; pp.pprint(pet_dictionary2)
# {'1': {'breed': 'bulldog', 'color': 'lilac', 'name': 'Emi', 'weight': 65},
# '2': {'breed': 'bulldog', 'color': 'blue', 'name': 'Henley', 'weight': 70},
# '3': {'breed': 'bulldog', 'color': 'white', 'name': 'Buford', 'weight': 95}}
如果可以更改上一个字典,那么你可以这样做:
def flip(k, v):
v.update(name=k)
return v.pop('age'), v
答案 4 :(得分:1)
通过几种理解,您可以进行如下转换:
new_dict = {
info['age']: {k: v for k, v in list(info.items()) + [('name', name)]
if k != 'age'}
for name, info in pet_dictionary.items()
}
pet_dictionary = {
'Buford': {'color': 'white', 'weight': 95, 'age': '3', 'breed': 'bulldog'},
'Henley': {'color': 'blue', 'weight': 70, 'age': '2', 'breed': 'bulldog'},
'Emi': {'color': 'lilac', 'weight': 65, 'age': '1', 'breed': 'bulldog'},
}
new_dict = {
info['age']: {k: v for k, v in list(info.items()) + [('name', name)]
if k != 'age'}
for name, info in pet_dictionary.items()
}
for dog in new_dict.items():
print(dog)
('3', {'color': 'white', 'weight': 95, 'breed': 'bulldog', 'name': 'Buford'})
('2', {'color': 'blue', 'weight': 70, 'breed': 'bulldog', 'name': 'Henley'})
('1', {'color': 'lilac', 'weight': 65, 'breed': 'bulldog', 'name': 'Emi'})
答案 5 :(得分:1)
使用pandas
,
import pandas as pd
pet_dictionary = {'Buford':{'color':'white', 'weight': 95, 'age':'3',
'breed':'bulldog'},
'Henley':{'color':'blue', 'weight': 70, 'age':'2',
'breed':'bulldog'},
'Emi':{'color':'lilac', 'weight': 65, 'age':'1',
'breed':'bulldog'},
}
pd.DataFrame.from_dict(pet_dictionary, orient='index') \
.reset_index() \
.rename(columns={'index': 'name'}) \
.set_index('age') \
.to_dict('index')
答案 6 :(得分:1)
在几行中完成此操作,没有任何其他库,但改变原始字典:
pet_dictionary = {
nested.pop('age'): nested.update({'name': name}) or nested
for name, nested in pet_dictionary.items()
}
还有额外的导入,但没有变异 pet_dictionary:
import copy
new_pet_dict = {
nested.pop('age'): nested.update({'name': name}) or nested
for name, nested in copy.deepcopy(pet_dictionary).items()
}
...原始pet_dictionary
保持不变。
<强>信息强>
最初,我发布了不同的答案,其中使用.pop
方法创建的新dict中的键和使用{**nested, 'name': name}
的嵌套dict,但它不起作用。这将是一个更清晰的解决方案,但AFAIK,解释器从右到左读取代码......显然使用这种方法是行不通的。
这是如何工作的呢?它看起来有点棘手,特别是行:
nested.update({'name': name}) or nested
但是让我们仔细看看。我们需要嵌套以使用name
键进行更新,但是返回None并改变对象。因此,or
的左侧部分始终为None
,我们希望在我们的词典理解中拥有dict
个对象。这里有short circuit evaluation
在Python中,如果第一个是假的,它总是返回第二个操作数。
无变异示例使用deepcopy
并改变ad-hoc副本,而不是原始字典。
答案 7 :(得分:0)
这是一个两个班轮:
##add new value, which was formerly the key
{k: v.update({'name':k}) for k,v in pet_dictionary.items()}
##reset keys to value of 'age'
new_pet = {v.get('age'): v for k,v in pet_dictionary.items()}