Python 如何合并具有相同密钥或不同密钥的多个DICT?
我有多个dict/键值对,如下所示:Python 如何合并具有相同密钥或不同密钥的多个DICT?,python,python-3.x,dictionary,merge,Python,Python 3.x,Dictionary,Merge,我有多个dict/键值对,如下所示: d1 = {key1: x1, key2: y1} d2 = {key1: x2, key2: y2} 我希望结果是一个新的dict(以最有效的方式,如果可能的话): 实际上,我希望结果d是: d = {key1: (x1.x1attrib, x2.x2attrib), key2: (y1.y1attrib, y2.y2attrib)} 如果有人告诉我如何得到第一个结果,我可以找出其余的结果。这里有一个通用的解决方案,可以处理任意数量的字典,
d1 = {key1: x1, key2: y1}
d2 = {key1: x2, key2: y2}
我希望结果是一个新的dict(以最有效的方式,如果可能的话):
实际上,我希望结果d是:
d = {key1: (x1.x1attrib, x2.x2attrib), key2: (y1.y1attrib, y2.y2attrib)}
如果有人告诉我如何得到第一个结果,我可以找出其余的结果。这里有一个通用的解决方案,可以处理任意数量的字典,当键只在某些字典中时:
from collections import defaultdict
d1 = {1: 2, 3: 4}
d2 = {1: 6, 3: 7}
dd = defaultdict(list)
for d in (d1, d2): # you can list as many input dicts as you want here
for key, value in d.items():
dd[key].append(value)
print(dd)
显示:
defaultdict(<type 'list'>, {1: [2, 6], 3: [4, 7]})
defaultdict(,{1:[2,6],3:[4,7]})
另外,要获取
.attrib
,只需将附加(value)
更改为附加(value.attrib)
假设所有关键字始终存在于所有dict中:
ds = [d1, d2]
d = {}
for k in d1.iterkeys():
d[k] = tuple(d[k] for d in ds)
注意:在Python 3.x中,使用以下代码:
ds = [d1, d2]
d = {}
for k in d1.keys():
d[k] = tuple(d[k] for d in ds)
如果dic包含numpy阵列:
ds = [d1, d2]
d = {}
for k in d1.keys():
d[k] = np.concatenate(list(d[k] for d in ds))
这里有一种方法,即使两个听写器没有相同的键,也可以使用:
d1 = {'a':'test','b':'btest','d':'dreg'}
d2 = {'a':'cool','b':'main','c':'clear'}
d = {}
for key in set(d1.keys() + d2.keys()):
try:
d.setdefault(key,[]).append(d1[key])
except KeyError:
pass
try:
d.setdefault(key,[]).append(d2[key])
except KeyError:
pass
print d
这将产生以下输入:
{'a': ['test', 'cool'], 'c': ['clear'], 'b': ['btest', 'main'], 'd': ['dreg']}
如果你只有d1和d2
from collections import defaultdict
d = defaultdict(list)
for a, b in d1.items() + d2.items():
d[a].append(b)
紧凑的可能性
d1={'a':1,'b':2}
d2={'c':3,'d':4}
context={**d1, **d2}
context
{'b': 2, 'c': 3, 'd': 4, 'a': 1}
Python 3.x更新 来自Eli Bendersky的回答: Python 3删除了dict.iteritems,而使用dict.items。 请参见Python wiki: 确保钥匙的顺序相同:
dict2_sorted = {i:dict2[i] for i in dict1.keys()}
keys = dict1.keys()
values = zip(dict1.values(), dict2_sorted.values())
dictionary = dict(zip(keys, values))
给出:
{'m': (2, 1), 'n': (4, 3)}
为了补充这两个列表解决方案,这里有一个处理单个列表的解决方案 示例列表(与NetworkX相关;此处手动格式化以便于阅读): 请注意相同边的重复值(由元组定义)。要将这些“值”与其对应的“键”进行比较: 参考资料
- [这条线]
- [Python文档]
- 来自blubb的回答:
还可以使用每个列表中的值直接形成元组
ds = [d1, d2]
d = {}
for k in d1.keys():
d[k] = (d1[k], d2[k])
如果对元组有特定的排序,这可能会很有用
ds = [d1, d2, d3, d4]
d = {}
for k in d1.keys():
d[k] = (d3[k], d1[k], d4[k], d2[k]) #if you wanted tuple in order of d3, d1, d4, d2
即使两个字典中的键不同,此函数也会合并两个dict:
def组合指令(d1、d2):
返回{
k:元组(d[k]表示d in(d1,d2),如果k in d)
对于集合中的k(d1.keys())|集合(d2.keys())
}
例如:
d1 = {
'a': 1,
'b': 2,
}
d2` = {
'b': 'boat',
'c': 'car',
}
combine_dict(d1, d2)
# Returns: {
# 'a': (1,),
# 'b': (2, 'boat'),
# 'c': ('car',)
# }
假设您拥有所有键的列表(您可以通过遍历所有字典并获取它们的键来获取此列表)。让我们把它命名为
listKeys
。此外:
是所需单个键的所有值的列表 合并listValues
:要合并的所有词典allDicts
这个库帮助了我,我有一个同名但值不同的嵌套键的dict列表,每个其他解决方案都会覆盖这些嵌套键
从deepmerge导入始终\u合并
def过程参数(参数):
临时列表=[]
对于参数中的x:
以开放(x,'r')作为流:
临时列表追加(yaml.安全加载(流))
始终返回合并。合并(*临时列表)
如果键嵌套:
d1 = { 'key1': { 'nkey1': 'x1' }, 'key2': { 'nkey2': 'y1' } }
d2 = { 'key1': { 'nkey1': 'x2' }, 'key2': { 'nkey2': 'y2' } }
收益率:
{'key1': {'nkey1': ('x1', 'x2')}, 'key2': {'nkey2': ('y1', 'y2')}}
假设有两个字典具有完全相同的键,下面是最简洁的方法(两种解决方案都应该使用python3)
d1={'a':1,'b':2,'c':3}
d2={'a':5,'b':6,'c':7}
#从其中一本字典中获取密钥
ks=[k代表d1.keys()中的k]
印刷品(ks)
['a','b','c']
#在可用键上调用每个字典中的值
d_merged={k:(d1[k],d2[k])表示k在ks}中
打印(d_合并)
{'a':(1,5),'b':(2,6),'c':(3,7)}
#将值合并为列表的步骤
d_merged={k:[d1[k],d2[k]]表示k在ks}
打印(d_合并)
{'a':[1,5],'b':[2,6],'c':[3,7]}
如果有两个字典有一些常用键,但有几个不同的键,那么应该准备一个所有键的列表
d1={'a':1,'b':2,'c':3,'d':9}
d2={'a':5,'b':6,'c':7,'e':4}
#从其中一本字典中获取密钥
d1_ks=[k代表d1.keys()中的k]
d2_ks=[k代表d2.keys()中的k]
all_ks=设置(d1_ks+d2_ks)
打印(全部)
['a','b','c','d','e']
#在可用键上调用每个字典中的值
d_merged={k:[d1.get(k),d2.get(k)]表示所有_-ks中的k}
打印(d_合并)
{'d':[9,无],'a':[1,5],'b':[2,6],'c':[3,7],'e':[None,4]}
对于具有相同键的两个或多个DICT,更好的表示方法是使用数据框pandas
IMO:
d1 = {"key1": "x1", "key2": "y1"}
d2 = {"key1": "x2", "key2": "y2"}
d3 = {"key1": "x3", "key2": "y3"}
d1_df = pd.DataFrame.from_dict(d1, orient='index')
d2_df = pd.DataFrame.from_dict(d2, orient='index')
d3_df = pd.DataFrame.from_dict(d3, orient='index')
fin_df = pd.concat([d1_df, d2_df, d3_df], axis=1).T.reset_index(drop=True)
fin_df
key1 key2
0 x1 y1
1 x2 y2
2 x3 y3
@萨利尔:我们可以假设每个键都存在于所有字典中吗?可能存在Hi Space_C0wb0y的重复,是的,所有字典中都存在键。指定所有DICT是否具有相同的键是绝对重要的。我认为OP希望值为
元组
而不是列表
@A A:这真的重要吗?在多输入dict的更一般的情况下,元组的构建将更为棘手,因为有些键不在任何地方,因此您可能需要从defaultdict
中生成一个正常的dict
,这样您就可以对不存在的键执行正常的dict
行为,等等:dd=dict(dd)
@Ned:good point,但这取决于最终使用的data@Eli:不,这没关系,但我只是想根据OP想要的东西来做,希望你能为元组找到一个解决方案:-)我想只要“在d1中为k”就行了。用d.get(k,None)代替d[k]@tahir这意味着dict具有不匹配的键,因此在d1
上迭代是不正确的(它可能会错过其他dict中的键)。对于Python3用户:d1.iterkeys()=d1.items(),在Python3.x中对我仍然不起作用。即使我的值不是数组,我也尝试过这个方法,而且它是有效的。但是,输出的值将是数组。问题是如何用同一个键合并dict。您的答案不是必需的。values()
中元素的顺序未定义,因此您可能正在合并来自无关键的值。我只是应用了更改,以便它现在可以捕获您的反馈。我认为更改不会解决问题。你需要使用sorted(d.items())
或sorted(d.keys())
来获得可预测的结果。你能举个例子来证明这一点吗?dict2_sorted是python中的一个排序字典!我做了一个sm
ec_num_collection_dict = {k:v for k, v in zip(ec_num_collection, ec_num_collection)}
print('\nec_num_collection_dict:\n{}'.format(dict(ec_num_collection)))
ec_num_collection_dict:
{(82, 433): ['1.1.1.1', '1.1.1.2'],
(22, 182): ['1.1.1.27'],
(22, 3785): ['1.2.4.1'],
(22, 36): ['6.4.1.1'],
(145, 36): ['1.1.1.37'],
(36, 154): ['2.3.3.1', '2.3.3.8'],
(36, 72): ['4.1.1.32'],
...}
ds = [d1, d2]
d = {}
for k in d1.keys():
d[k] = (d1[k], d2[k])
ds = [d1, d2, d3, d4]
d = {}
for k in d1.keys():
d[k] = (d3[k], d1[k], d4[k], d2[k]) #if you wanted tuple in order of d3, d1, d4, d2
d1 = {
'a': 1,
'b': 2,
}
d2` = {
'b': 'boat',
'c': 'car',
}
combine_dict(d1, d2)
# Returns: {
# 'a': (1,),
# 'b': (2, 'boat'),
# 'c': ('car',)
# }
result = {}
for k in listKeys:
listValues = [] #we will convert it to tuple later, if you want.
for d in allDicts:
try:
fileList.append(d[k]) #try to append more values to a single key
except:
pass
if listValues: #if it is not empty
result[k] = typle(listValues) #convert to tuple, add to new dictionary with key k
d1 = { 'key1': { 'nkey1': 'x1' }, 'key2': { 'nkey2': 'y1' } }
d2 = { 'key1': { 'nkey1': 'x2' }, 'key2': { 'nkey2': 'y2' } }
ds = [d1, d2]
d = {}
for k in d1.keys():
for k2 in d1[k].keys():
d.setdefault(k, {})
d[k].setdefault(k2, [])
d[k][k2] = tuple(d[k][k2] for d in ds)
{'key1': {'nkey1': ('x1', 'x2')}, 'key2': {'nkey2': ('y1', 'y2')}}
d1 = {"key1": "x1", "key2": "y1"}
d2 = {"key1": "x2", "key2": "y2"}
d3 = {"key1": "x3", "key2": "y3"}
d1_df = pd.DataFrame.from_dict(d1, orient='index')
d2_df = pd.DataFrame.from_dict(d2, orient='index')
d3_df = pd.DataFrame.from_dict(d3, orient='index')
fin_df = pd.concat([d1_df, d2_df, d3_df], axis=1).T.reset_index(drop=True)
fin_df
key1 key2
0 x1 y1
1 x2 y2
2 x3 y3