基于匹配键的值比较两个字典

3

我有两个字典:

S = {0: [1, 2, 3, 4], 
     1: [5, 6, 7, 8, 9, 10], 
     2: [11, 12, 13, 14, 15]}

R = {0: [1, 2, 8], 
    1: [8, 5, 10, 11, 15], 
    2: []}

我需要查找给定关键字是否与列表中的任何数字匹配。如果匹配,则将数字替换为“X”。
结果应该如下所示:
    F = {0: ['X', 'X', 3, 4], 
         1: ['X', 6, 7, 8, 9, 'X'], 
         2: [11, 12, 13, 14, 15]}
or 

F = [['X', 'X', 3, 4], ['X', 6, 7, 8, 9, 'X'], [11, 12, 13, 14, 15]]

对于 F 是第三个字典还是一个列表的列表,我不太在意。

我的代码如下:

Solution = []

for x in S.values():
    for y in R.values():
        for j in y:
            for n, i in enumerate(x):
                if j == i:
                    x[n] = 'X'
                    
    Solution.append(x)  

问题在于我正在将R中的每个值与S中的每个字典值进行比较。 我不明白如何独立地比较例如[1,2,3,4]和[1,2,8],而不考虑[5,6,7,8,9,10]与[8,5,10,11,15]。
2个回答

5

你可以使用集合

# This modifies S in place; use a new dict if you want to keep S
for k,li1 in S.items():
    li2=R.get(k,[])
    diff=set(li1)-set(li2)
    S[k]=[e if e in diff else 'X' for e in li1] 


>>> S
{0: ['X', 'X', 3, 4], 1: ['X', 6, 7, 'X', 9, 'X'], 2: [11, 12, 13, 14, 15]}

使用 差集 - 操作,您可以获取仅出现在第一个列表中但不同时出现在两个列表中的元素:
>>> set([1,2,3,4]) - set([2,3,8])
{1, 4}

一旦你知道了这个,改变列表就很容易了。

如果你想要一个包含多个列表的列表,那么可以使用列表推导式:

LoL=[[e if e in set1 else 'X' for e in li1]
    for li1,set1 in 
        zip(S.values(), {k:set(li1)-set(R.get(k,[])) 
            for k,li1 in S.items()}.values())]

>>> LoL
[['X', 'X', 3, 4], ['X', 6, 7, 'X', 9, 'X'], [11, 12, 13, 14, 15]]

但我个人认为,循环更容易理解...


没错,这完全有道理。非常感谢你的帮助。 - SQL_Roundabout

3
你可以使用字典推导式:
``` 你可以使用字典推导式: ```
F = {k: ["X" if vv in R.get(k, []) else vv for vv in v] for k, v in S.items()}
print(F)

输出:

{0: ['X', 'X', 3, 4], 1: ['X', 6, 7, 'X', 9, 'X'], 2: [11, 12, 13, 14, 15]}

1
聪明但潜在缓慢。 - dawg
1
非常感谢。您的解决方案对我也起作用了。 - SQL_Roundabout

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接