在python中修改嵌套字典中的键和值

时间:2018-01-31 03:11:35

标签: python dictionary nested

我正在使用嵌套字典,并且我试图弄清楚如何有效地修改某些嵌套和非嵌套键/值。简而言之,我试图做到以下几点:

  1. 获取嵌套值并使用非嵌套键切换
  2. 重命名嵌套密钥。
  3. 这是我正在使用的字典的基本示例:

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

    我了解如何逐个手动执行此操作,但我不确定以更优雅/最佳方式进行所有这些更改的最佳方法是什么。

8 个答案:

答案 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()}