如何使用 Python 将由列表组成的值与字典中的常见项目组合?
How to combine values composed of lists with common items in a dictionary using Python?
我有一个类似于以下内容的字典:
dict1 = {'key1':['1','2','3'],'key2':['3','4','5'],'key3':['6','7','8']}
我想合并所有具有至少一个共同元素的键,结果是。例如,生成的字典应如下所示:
dict1 = {'key1':['1','2','3','4','5'],'key3':['6','7','8']}
请注意key2是如何被删除的。被淘汰的是key1还是key2都无所谓。
我只知道能够识别重复,但不知道如何以迭代方式合并它们。谢谢
这对你有用吗?请注意,由于字典中元素的顺序是任意的,您无法保证哪些键最终会被插入到输出字典中。
dict_out = {}
processed = set()
for k1, v1 in dict_in.items():
if k1 not in processed:
processed.add(k1)
vo = v1
for k2, v2 in dict_in.items():
if k2 not in processed and set(v1) & set(v2):
vo = sorted(list(set(vo + v2)))
processed.add(k2)
dict_out[k1] = vo
这是为了:
dict_in = {'key1': ['1', '2', '3'], 'key2': ['3', '4', '5'], 'key3': ['6', '7', '8']}
给出:
{'key1': {'1', '2', '3', '4', '5'}, 'key3': ['6', '7', '8']}
还有:
dict_in = {'key1': ['1', '2', '3'], 'key2': ['3', '4', '5'],
'key3': ['6', '7', '8'], 'key4': ['7', '9']}
给出:
{'key1': {'1', '2', '3', '4', '5'}, 'key3': {'6', '7', '8', '9'}}
最后,为了:
dict_in = {'key1': ['1', '2', '3'], 'key2': ['3', '4', '5'],
'key3': ['6', '7', '8'], 'key4': ['5', '6', '7']}
它给出:
{'key1': {'1', '2', '3', '4', '5'}, 'key3': {'5', '6', '7', '8'}}
编辑
OP 要求甚至合并的结果也应该相互合并。为此,我们可以将上面的代码包装在一个循环中,如下所示:
d = dict_in
processed = set([None])
while processed:
dict_out = {}
processed = set()
for k1, v1 in d.items():
if k1 not in processed:
vo = v1
for k2, v2 in d.items():
if k1 is not k2 and set(vo) & set(v2):
vo = sorted(list(set(vo + v2)))
processed.add(k2)
dict_out[k1] = vo
d = dict_out
然后,对于:
dict_in = {'key1': ['1', '2', '3'], 'key2': ['3', '4', '5'],
'key3': ['6', '7', '8'], 'key4': ['5', '6', '7']}
我们得到:
{'key4': ['1', '2', '3', '4', '5', '6', '7', '8']}
并为:
dict_in = {'key1': ['1', '2', '3'], 'key2': ['3', '4', '5'],
'key3': ['4', '6', '7'], 'key4': ['8', '9']}
我们得到:
{'key1': ['1', '2', '3', '4', '5', '6', '7'], 'key4': ['8', '9']}
如果你想改变原来的字典,你需要复制:
vals = {k: set(val) for k, val in dict1.items()}
for key, val in dict1.copy().items():
for k, v in vals.copy().items():
if k == key:
continue
if v.intersection(val):
union = list(v.union(val))
dict1[key] = union
del vals[k]
del dict1[k]
如果你想合并所有:
vals = {k: set(val) for k, val in dict1.items()}
unioned = set()
srt = sorted(dict1.keys())
srt2 = srt[:]
for key in srt:
for k in srt2:
if k == key:
continue
if vals[k].intersection(dict1[key]) and key not in unioned:
unioned.add(k)
dict1[key] = list(vals[k].union(dict1[key]))
srt2.remove(k)
for k in unioned:
del dict1[k]
我有一个更简洁的方法。
我认为它更具可读性和易于理解。您可以参考如下:
dict1 = {'key1':['1','2','3'],'key2':['3','4','5'],'key3':['6','7','8']}
# Index your key of dict
l = list(enumerate(sorted(dict1.keys())))
# nested loop
for i in xrange(len(dict1)):
for j in xrange(i+1,len(dict1)):
i_key, j_key = l[i][1], l[j][1]
i_value, j_value = set(dict1[i_key]), set(dict1[j_key])
# auto detect: if the values have common element to do union
if i_value & j_value:
union_list = sorted(list(i_value | j_value))
dict1[i_key] = union_list
del dict1[j_key]
print dict1
#{'key3': ['6', '7', '8'], 'key1': ['1', '2', '3', '4', '5']}
我有一个类似于以下内容的字典:
dict1 = {'key1':['1','2','3'],'key2':['3','4','5'],'key3':['6','7','8']}
我想合并所有具有至少一个共同元素的键,结果是。例如,生成的字典应如下所示:
dict1 = {'key1':['1','2','3','4','5'],'key3':['6','7','8']}
请注意key2是如何被删除的。被淘汰的是key1还是key2都无所谓。 我只知道能够识别重复,但不知道如何以迭代方式合并它们。谢谢
这对你有用吗?请注意,由于字典中元素的顺序是任意的,您无法保证哪些键最终会被插入到输出字典中。
dict_out = {}
processed = set()
for k1, v1 in dict_in.items():
if k1 not in processed:
processed.add(k1)
vo = v1
for k2, v2 in dict_in.items():
if k2 not in processed and set(v1) & set(v2):
vo = sorted(list(set(vo + v2)))
processed.add(k2)
dict_out[k1] = vo
这是为了:
dict_in = {'key1': ['1', '2', '3'], 'key2': ['3', '4', '5'], 'key3': ['6', '7', '8']}
给出:
{'key1': {'1', '2', '3', '4', '5'}, 'key3': ['6', '7', '8']}
还有:
dict_in = {'key1': ['1', '2', '3'], 'key2': ['3', '4', '5'],
'key3': ['6', '7', '8'], 'key4': ['7', '9']}
给出:
{'key1': {'1', '2', '3', '4', '5'}, 'key3': {'6', '7', '8', '9'}}
最后,为了:
dict_in = {'key1': ['1', '2', '3'], 'key2': ['3', '4', '5'],
'key3': ['6', '7', '8'], 'key4': ['5', '6', '7']}
它给出:
{'key1': {'1', '2', '3', '4', '5'}, 'key3': {'5', '6', '7', '8'}}
编辑
OP 要求甚至合并的结果也应该相互合并。为此,我们可以将上面的代码包装在一个循环中,如下所示:
d = dict_in
processed = set([None])
while processed:
dict_out = {}
processed = set()
for k1, v1 in d.items():
if k1 not in processed:
vo = v1
for k2, v2 in d.items():
if k1 is not k2 and set(vo) & set(v2):
vo = sorted(list(set(vo + v2)))
processed.add(k2)
dict_out[k1] = vo
d = dict_out
然后,对于:
dict_in = {'key1': ['1', '2', '3'], 'key2': ['3', '4', '5'],
'key3': ['6', '7', '8'], 'key4': ['5', '6', '7']}
我们得到:
{'key4': ['1', '2', '3', '4', '5', '6', '7', '8']}
并为:
dict_in = {'key1': ['1', '2', '3'], 'key2': ['3', '4', '5'],
'key3': ['4', '6', '7'], 'key4': ['8', '9']}
我们得到:
{'key1': ['1', '2', '3', '4', '5', '6', '7'], 'key4': ['8', '9']}
如果你想改变原来的字典,你需要复制:
vals = {k: set(val) for k, val in dict1.items()}
for key, val in dict1.copy().items():
for k, v in vals.copy().items():
if k == key:
continue
if v.intersection(val):
union = list(v.union(val))
dict1[key] = union
del vals[k]
del dict1[k]
如果你想合并所有:
vals = {k: set(val) for k, val in dict1.items()}
unioned = set()
srt = sorted(dict1.keys())
srt2 = srt[:]
for key in srt:
for k in srt2:
if k == key:
continue
if vals[k].intersection(dict1[key]) and key not in unioned:
unioned.add(k)
dict1[key] = list(vals[k].union(dict1[key]))
srt2.remove(k)
for k in unioned:
del dict1[k]
我有一个更简洁的方法。
我认为它更具可读性和易于理解。您可以参考如下:
dict1 = {'key1':['1','2','3'],'key2':['3','4','5'],'key3':['6','7','8']}
# Index your key of dict
l = list(enumerate(sorted(dict1.keys())))
# nested loop
for i in xrange(len(dict1)):
for j in xrange(i+1,len(dict1)):
i_key, j_key = l[i][1], l[j][1]
i_value, j_value = set(dict1[i_key]), set(dict1[j_key])
# auto detect: if the values have common element to do union
if i_value & j_value:
union_list = sorted(list(i_value | j_value))
dict1[i_key] = union_list
del dict1[j_key]
print dict1
#{'key3': ['6', '7', '8'], 'key1': ['1', '2', '3', '4', '5']}