理解Python中字典的交集和差异

3

我是新手Python程序员,遇到了这个问题,由于英语不是我的母语,所以在解决这个问题时有点困难,但按我理解这个问题写了我的代码,请问我是否正确?如果不正确,请改进我的代码或提供你的代码。

假设您有两个字典d1和d2,每个字典都有整数键和整数值。您还得到一个函数f,它接受两个整数,在它们上执行未知操作,并返回一个值。

编写一个名为dict_interdiff的函数,它接受两个字典(d1和d2)。该函数将返回两个字典的元组:d1和d2的交集字典以及d1和d2的差异字典,计算如下:

'''交集:交集字典的键是d1和d2中共同的键。要获取交集字典的值,请查看d1和d2中的公共键,并将函数f应用于这些键的值--d1中公共键的值是函数的第一个参数,d2中公共键的值是函数的第二个参数。不要在dict_interdiff代码中实现f--假定它在外部已定义。

差异:差异字典中的键值对是(a)仅在d1中出现而不在d2中的每个键-值对或(b)仅在d2中出现而不在d1中的每个键-值对。'''

以下是两个示例:

'''If f(a, b) returns a + b
d1 = {1:30, 2:20, 3:30, 5:80}
d2 = {1:40, 2:50, 3:60, 4:70, 6:90}
then dict_interdiff(d1, d2) 
returns ({1: 70, 2: 70, 3: 90}, {4: 70, 5: 80, 6: 90})


If f(a, b) returns a > b
d1 = {1:30, 2:20, 3:30}
d2 = {1:40, 2:50, 3:60}
then dict_interdiff(d1, d2)
returns ({1: False, 2: False, 3: False}, {})'''

这是我的代码

def dict_interdiff(d1, d2):

a=d1.keys()
b=d2.keys()
c=d1.values()
d=d2.values()
e=()
u={}
f=[]
g=[]
for i in range(max(a,b)):
    if a[i]==b[i]:
        u=f(a[i],b[i])
    elif a[i] not in b:
         t=c.find(a[i])
         f.append(c[t])
         g.append(a[i])
         k=dict(zip(g,f))
    elif b[i] not in a:
         t=c.find(b[i])
         f.append(d[t])
         g.append(b[i])
         k=dict(zip(g,f))
    e+(u,)+(k,)
return e    

此外,我无法检查我的代码,因为它假定f已定义,而我不知道这一点,因此无法在我的解释器中运行。


@zondo 能否优化一下我的代码或者提供您的解决方案? - user5936276
我觉得我做不到。我试图通过使用max(len(a), len(b))而不是max(a, b)来解决这个问题,但是我又遇到了另一个错误,我不知道该如何解决。 - zondo
你正在把这些字典看做数组,这并不是一个有帮助的方法。字典是哈希表 - 键和相应的值。考虑到这些键可能是任何东西,而不仅仅是整数,你就能明白访问器失败的原因了。请查看下面的示例解决方案... - F1Rumors
区别在于对称差异,如果您想要从a和b中获取唯一的键。 - Padraic Cunningham
@PadraicCunningham,您能否简化您的问题,因为对我来说太技术化了,很抱歉但我不知道什么是可哈希的(hashable). - user5936276
显示剩余3条评论
3个回答

0

根据这些差异,似乎很简单明了。

def dict_interdiff(d1, d2, f):
  sameKeys = set(d1.keys()) & set(d2.keys())  # Keys in both dicts
  same     = dict([(k, f(d1[k],d2[k])) for k in sameKeys])  # f applied
  diffKeys = set(d1.keys())^set(d2.keys())   # Keys in single dict
  diffs    = dict([(k,d1.get(k, d2.get(k))) for k in diffKeys])  # values
  return (same,diffs,)

我想我应该分享一下确认它产生了预期的结果!

>>> dict_interdiff(d1, d2, f)
({1: 70, 2: 70, 3: 90}, {4: 70, 5: 80, 6: 90})

0

你可以使用字典的集合操作来完成所有操作:

def dict_interdiff(d1, d2):
    # symmetric difference, keys in either d1 or d2 but not both.
    sym_diff = d1.viewkeys() ^ d2
    # intersection, keys that are common to both d1 and d2.
    intersect = d1.viewkeys() & d2
    # apply f on values of the keys that common to both dicts.
    a = {k: f(d1[k], d2[k]) for k in intersect}
    b = {k: d1[k] for k in sym_diff & d1.viewkeys()}
    # add key/value pairings from d2 using keys that appear in sym_diff 
    b.update({k: d2[k] for k in sym_diff & d2.viewkeys()})
    return a,b

sym_diff = d1.viewkeys() ^ d2 获取对称差,即出现在ab中的键,但不同时存在于两者

intersect = d1.viewkeys() & d2 获取键的交集,即出现在d1和d2中的键都会被保留

b = {k: d1[k] for k in sym_diff.viewkeys() & d1} 创建一个字典,其中包含sym_diff集合中出现在d1中的键。

b.update({k: d2[k] for k in sym_diff.viewkeys() & d2}) 更新b,添加d2中的键/值对,使用出现在sym_diff中的键,以便您最终获得一个字典b,其中包含sym_diff集合中的所有键及其值。


谢谢,它可以工作,但对于dict_interdiff({1: 2}, {2: 1}),它返回了Traceback (most recent call last): File "submission.py", line 5, in dict_interdiff a = {k:f(d1[k],d2[k]) for k in sym_diff} File "submission.py", line 5, in <dictcomp> a = {k:f(d1[k],d2[k]) for k in sym_diff} KeyError: 1 - user5936276
@jamessmith,是的,请查看eddit。 - Padraic Cunningham
抱歉浪费您的时间,但是您能解释一下您的代码在做什么吗?(我是新手,对于阅读代码比较慢) - user5936276
1
@ Padraic Cunningham非常感谢你(这就是我喜欢这个社区的原因,它一直帮助到底),像你这样优秀的人使得这一切成为可能。再次感谢。 - user5936276
1
@ Padraic Cunningham,关于这个问题,你解释得非常清楚,谢谢。 - user5936276
显示剩余2条评论

0

您可以通过在文件中自己定义代码来随时检查它。这是我的简单实现:

def dict_interdiff(d1, d2):
'''
d1, d2: dicts whose keys and values are integers
Returns a tuple of dictionaries according to the instructions above
'''
# Your code here
orderedintersect={}
ordereddiff={}
done=d1.copy()
dtwo=d2.copy()
for key in done:
    if key in dtwo:
        orderedintersect[key]=f(done[key],dtwo[key])
        del d1[key]
        del d2[key]
d1.update(d2)
for i in sorted(d1.keys()):
    ordereddiff[i]=d1[i]
return orderedintersect,ordereddiff   

def f(a,b):
    return a+b    

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