简体   繁体   English

如何合并多个字典

[英]How to merge multiple dictionaries

I have main_dict. 我有main_dict。

main_dict={'name1':{'key1':'value1', 'key2':'value2'}, 'name2':{'key1':'value3', 'key2':'value8'} ... }

I have 2 other dictionaries which brings some more data to be added in the main_dict. 我还有2个其他字典,这些字典带来了更多要添加到main_dict中的数据。

like, 喜欢,

**age_dict= {{'age':'age_value1', 'name': 'name1'}, {'age':'age_value1', 'name': 'name2'}}
gender_dict= {{'gender':'gen_value1', 'name': 'name1'}, {'gender':'gen_value2', 'name': 'name2'}}**

Now i would like to make some loops and merge these dictionaries such that it checks for the same name and takes values from age and gender dictionaries and create keys 'age' , 'gender' and add them into main_dict. 现在,我想进行一些循环并合并这些词典,以便它检查相同的名称并从年龄和性别词典中获取值,并创建键“ age”,“ gender”并将其添加到main_dict中。

For now i have done this, but i think django can help to do this in a single way: 现在我已经做到了,但是我认为django可以以一种单一的方式帮助实现这一点:

for user in age_dict:
    for key, value in main_dict.iteritems():
        if key == user['name']:
            value['age'] = user['age_value']

for user in gender_dict:
    for key, value in main_dict.iteritems():
        if key == user['name']:
            value['gender'] = user['gen_value']

EDIT: Modified age_dict and gender_dict. 编辑:修改了age_dict和gender_dict。

General hint: if you are doing something like 一般提示:如果您正在做类似的事情

for key, val in some_dict.iteritems():
    if key == some_value:
       do_something(val)

you are most likely doing it wrong , because you are not using the dictionaries very purpose: accessing elements by their keys. 您最有可能做错了 ,因为您使用字典的目的不是很明确:通过其键访问元素。 Instead, do 相反,做

do_something(some_dict[key])

and use exceptions if you can't be sure that somedict[key] exists. 如果无法确定somedict[key]存在,请使用例外。


You don't have to interate over dictionaries to find the appropriate key. 您不必遍历字典即可找到适当的键。 Just access it directly, that's what dictionaries are for: 只需直接访问它,这就是字典的用途:

main_dict={'name1':{'key1':'value1', 'key2':'value2'}, 'name2':{'key1':'value3', 'key2':'value8'}}


age_dicts = [{'age':'age_value1', 'name': 'name1'}, 'age':'age_value1', 'name': 'name2'}]
gender_dicts = [{'gender':'gen_value1', 'name': 'name1'}, 'gender':'gen_value2', 'name': 'name2'}]

for dct in age_dicts:
    main_dict[dct['name']]['age'] = dct['age']

for dct in gender_dicts:
    main_dict[dct['name']]['gender'] = dct['gender']

Specific answer to the pre-edit case: 针对预编辑案例的具体答案:

age_dict= {'name1':'age_value1', 'name2':'age_value2'}
gender_dict= {'name1':'gen_value1', 'name2':'gen_value2'}

If you are sure that gender_dict and age_dict provide values for each name, it's as easy as 如果你确信gender_dictage_dict为每名提供值,它是一样简单

for name, dct in main_dict.iteritems():
   dct['age'] = age_dict[name]
   dct['gender'] = gender_dict[name]

If there are names without entries in the other dictionaries, you can use exceptions: 如果其他词典中有没有条目的名称,则可以使用例外:

for name, dct in main_dict.iteritems():
   try:
       dct['age'] = age_dict[name]
   except KeyError:    # no such name in age_dict
       pass
   try:
       dct['gender'] = gender_dict[name]
   except KeyError:    # no such name in gender_dict
       pass

The setdefault method of dict looks up a key, and returns the value if found. dict的setdefault方法查找键,如果找到,则返回值。 If not found, it returns a default, and also assigns that default to the key. 如果找不到,它将返回默认值,并将该默认值分配给密钥。

super_dict = {}
for d in dicts:
    for k, v in d.iteritems():
        super_dict.setdefault(k, []).append(v)

Also, you might consider using a defaultdict. 另外,您可以考虑使用defaultdict。 This just automates setdefault by calling a function to return a default value when a key isn't found. 这只是通过调用一个函数以在找不到键时返回默认值来自动执行setdefault的操作。

import collections
super_dict = collections.defaultdict(list)
for d in dicts:
    for k, v in d.iteritems():
        super_dict[k].append(v)

Also, as Sven Marnach astutely observed, you seem to want no duplication of values in your lists. 而且,正如Sven Marnach的观察一样,您似乎不希望列表中的值重复。 In that case, set gets you what you want: 在这种情况下,set可以满足您的需求:

import collections
super_dict = collections.defaultdict(set)
for d in dicts:
    for k, v in d.iteritems():
        super_dict[k].add(v)

So you want use age_dict and gender_dict to enrich the values for the keys in main_dict . 所以,你要使用age_dictgender_dict以丰富的价值在按键main_dict Well, given Python guarantees average dict lookup to be constant you are constrained only by the number of keys in main_dict and you can reach the enrichment in O(n) where n is the size of the dictionary: 好吧,考虑到Python保证平均dict查找是恒定的,您仅受main_dict中键的数量的约束,并且可以达到O(n)的丰富性,其中n是字典的大小:

for user_name, user_info in main_dict.items():
  if user_name in gender_dict:
    user_info['gender'] = gender_dict[user_name]
  if user_name in age_dic:
    user_info['age'] = age_dict[user_name]

And a fancy function doing this in a generic way: 和一个花哨的功能,以一种通用的方式做到这一点:

def enrich(target, **complements):
  for user_name, user_info in target.items():
    for complement_key, complemented_users in complements.items():
      if user_name in complemented_users:
        user_info[complement_key] = complemented_users[user_name]

enrich(main_dict, age=age_dict, gender=gender_dict)

Even if you see two nested loops, it is more likely the number of users in main_dict dominates over the number of complementary dictionaries. 即使您看到两个嵌套循环, main_dict的用户数量也有可能超过补充词典的数量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM