我有多个dicts /键值对,如下所示:
d1 = {key1: x1, key2: y1}
d2 = {key1: x2, key2: y2}
我希望结果是一个新的词典(如果可能的话,以最有效的方式):
d = {key1: (x1, x2), key2: (y1, y2)}
实际上,我希望结果d为:
d = {key1: (x1.x1attrib, x2.x2attrib), key2: (y1.y1attrib, y2.y2attrib)}
如果有人告诉我如何获得第一个结果,我可以弄清楚其余部分。
答案 0 :(得分:51)
这是一个通用的解决方案,可以处理任意数量的字典,例如当键只在某些字典中时:
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.iteritems():
dd[key].append(value)
print(dd)
节目:
defaultdict(<type 'list'>, {1: [2, 6], 3: [4, 7]})
另外,要获取.attrib
,只需将append(value)
更改为append(value.attrib)
答案 1 :(得分:17)
假设所有密钥始终存在于所有dicts中:
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))
答案 2 :(得分:3)
如果你只有d1和d2,
from collections import defaultdict
d = defaultdict(list)
for a, b in d1.items() + d2.items():
d[a].append(b)
答案 3 :(得分:2)
这是一种可以使用的方法,即使两个词典都没有相同的键也可以使用:
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']}
答案 4 :(得分:1)
dict1 = {'m': 2, 'n': 4}
dict2 = {'n': 3, 'm': 1}
确保按键顺序相同:
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)}
答案 5 :(得分:1)
假定您具有所有键的列表(可以通过遍历所有字典并获取其键来获得此列表)。我们将其命名为listKeys
。另外:
listValues
是您想要的单个键的所有值的列表
合并。allDicts
:您要合并的所有字典。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
答案 6 :(得分:0)
def merge(d1, d2, merge):
result = dict(d1)
for k,v in d2.iteritems():
if k in result:
result[k] = merge(result[k], v)
else:
result[k] = v
return result
d1 = {'a': 1, 'b': 2}
d2 = {'a': 1, 'b': 3, 'c': 2}
print merge(d1, d2, lambda x, y:(x,y))
{'a': (1, 1), 'c': 2, 'b': (2, 3)}
答案 7 :(得分:0)
Python 3.x更新
来自Eli Bendersky回答:
Python 3删除了dict.iteritems而不是使用dict.items。 请参阅Python wiki:https://wiki.python.org/moin/Python3.0
{{1}}
答案 8 :(得分:0)
作为对两列表解决方案的补充,这是用于处理单个列表的解决方案。
示例列表(与NetworkX相关;在此处手动设置格式以提高可读性)
ec_num_list = [((src, tgt), ec_num['ec_num']) for src, tgt, ec_num in G.edges(data=True)]
print('\nec_num_list:\n{}'.format(ec_num_list))
ec_num_list:
[((82, 433), '1.1.1.1'),
((82, 433), '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'),
((36, 154), '2.3.3.8'),
((36, 72), '4.1.1.32'),
...]
请注意相同边(由元组定义)的重复值。要将这些“值”整理为对应的“键”:
from collections import defaultdict
ec_num_collection = defaultdict(list)
for k, v in ec_num_list:
ec_num_collection[k].append(v)
print('\nec_num_collection:\n{}'.format(ec_num_collection.items()))
ec_num_collection:
[((82, 433), ['1.1.1.1', '1.1.1.2']), ## << grouped "values"
((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']), ## << grouped "values"
((36, 72), ['4.1.1.32']),
...]
如果需要,将该列表转换为字典:
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'],
...}
参考
答案 9 :(得分:0)
来自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
答案 10 :(得分:0)
即使两个字典中的键不同,此方法也会合并两个字典:
def combine_dict(d1, d2):
combined = {}
for k in set(d1.keys()) | set(d2.keys()):
combined[k] = tuple(d[k] for d in [d1, d2] if k in d)
return combined
示例:
d1 = {
'a': 1,
'b': 2,
}
d2` = {
'b': 'boat',
'c': 'car',
}
combine_dict(d1, d2)
# Returns: {
# 'a': (1,),
# 'b': (2, 'boat'),
# 'c': ('car',)
# }
答案 11 :(得分:0)
这个库对我有帮助,我有一个具有相同名称但值不同的嵌套键的字典列表,所有其他解决方案都将覆盖这些嵌套键。
https://pypi.org/project/deepmerge/
from deepmerge import always_merger
def process_parms(args):
temp_list = []
for x in args:
with open(x, 'r') as stream:
temp_list.append(yaml.safe_load(stream))
return always_merger.merge(*temp_list)
答案 12 :(得分:0)
如果键嵌套:
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')}}
答案 13 :(得分:0)
假设有两个具有完全相同键的字典,以下是最简洁的方法(两种解决方案都应使用 python3)。
d1 = {'a': 1, 'b': 2, 'c':3}
d2 = {'a': 5, 'b': 6, 'c':7}
# get keys from one of the dictionary
ks = [k for k in d1.keys()]
print(ks)
['a', 'b', 'c']
# call values from each dictionary on available keys
d_merged = {k: (d1[k], d2[k]) for k in ks}
print(d_merged)
{'a': (1, 5), 'b': (2, 6), 'c': (3, 7)}
# to merge values as list
d_merged = {k: [d1[k], d2[k]] for k in ks}
print(d_merged)
{'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}
# get keys from one of the dictionary
d1_ks = [k for k in d1.keys()]
d2_ks = [k for k in d2.keys()]
all_ks = set(d1_ks + d2_ks)
print(all_ks)
['a', 'b', 'c', 'd', 'e']
# call values from each dictionary on available keys
d_merged = {k: [d1.get(k), d2.get(k)] for k in all_ks}
print(d_merged)
{'d': [9, None], 'a': [1, 5], 'b': [2, 6], 'c': [3, 7], 'e': [None, 4]}
答案 14 :(得分:0)
具有相同键的两个或多个字典的更好表示是 pandas Data Frame
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
答案 15 :(得分:-4)
紧凑的可能性
d1={'a':1,'b':2}
d2={'c':3,'d':4}
context={**d1, **d2}
context
{'b': 2, 'c': 3, 'd': 4, 'a': 1}