首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python查找两个字典是否按值对键进行相同的分区。

Python查找两个字典是否按值对键进行相同的分区。
EN

Stack Overflow用户
提问于 2019-06-26 02:31:47
回答 4查看 527关注 0票数 1

做以下事情的最毕达通的方法是什么:假设我有两本字典AB。现在,字典的常规python等式将检查每个字典中的值和键是否相同,如果这对字典的每个元素都有效,那么它们是相等的。我想对此进行修改,使之考虑一个字典,如果对于在A中具有相同值的所有键集,则该集合中的每个元素在B中具有相同的值,但不一定与A中的相同。

示例:

代码语言:javascript
复制
A = {'A':1, 'B':4, 'C':1}
B = {'A':9, 'B':2, 'C':9}

这里是A == B。从本质上说,这个字典代表了一组集合,我想在它之上实现set相等。

我的尝试

代码语言:javascript
复制
def eq(a,b):
    if not a.keys() == b.keys():
        return False
    for grouping in ({k for k in a.keys() if a[k] == v} for v in a.values()):
        if not len(set(b[x] for x in grouping)) == 1:
            return False
    return True

我真的不喜欢这种方法,因为它不会短路,因为必须消耗整个发电机才能将其转换为一组。其思想是将第一个集合划分为组,这样每个组中的每个元素都具有相同的值。然后,我想确保对于每个分组,分组元素的值在另一个集合中是相同的。

编辑很抱歉我不能解释得更清楚,我会给出更多的例子。考虑这个问题的一个更简单的方法是:我可以将任何字典转换成一组集合,如下所示:

代码语言:javascript
复制
A = {'A':3, 'B':3, 'C':3, 'R':4, 'T':4}
A = {{'A', 'B', 'C'}, {'R', 'T'}}
B = {'A':[], 'B':[], 'C':[], 'R':"", 'T':""}
B = {{'A', 'B', 'C'}, {'R', 'T'}}
A == B
EN

回答 4

Stack Overflow用户

发布于 2019-06-26 02:51:47

有些变化,我只能做到:

代码语言:javascript
复制
def eq(a,b):
    if not a.keys() == b.keys():
        return False
    for x, y in zip(a.values(), b.values()):
        if not sorted([key for key in a.keys() if a[key] == x]) == sorted([key for key in b.keys() if b[key] == y]):
            return False
    return True

但稍微干净一点,就会是:

代码语言:javascript
复制
def eq(a,b):
    d1 = {}
    d2 = {}
    for (x, y), (i, j) in zip(a.items(), b.items()):
        d1.setdefault(y, []).append(x)
        d2.setdefault(j, []).append(i)
    return [sorted(i) for i in d1.values()] == [sorted(i) for i in d2.values()]

或更短:

代码语言:javascript
复制
def eq(a,b):
    d1 = {y: sorted([i for i in a.keys() if a[i] == y]) for x, y in a.items()}
    d2 = {y: sorted([i for i in b.keys() if b[i] == y]) for x, y in b.items()}
    return list(d1.values()) == list(d2.values())
票数 4
EN

Stack Overflow用户

发布于 2019-06-26 02:52:17

基于@pault建议的一种方法是创建键的值字典,然后查看两个字典的值是否以相同的方式组合在一起。

我还对反向字典的值进行排序,以处理顺序,以及比较它们时的最终值列表。

代码语言:javascript
复制
from collections import defaultdict

def eq(A, B):

    rev_A = defaultdict(list)
    rev_B = defaultdict(list)

    #Create the reverse dictionary
    for k, v in A.items():
        #If v is a list, convert it to tuple to make a hashable key
        if isinstance(v, list):
            rev_A[tuple(v)].append(k)
        else:
            rev_A[v].append(k)

    for k, v in B.items():
        if isinstance(v, list):
            rev_B[tuple(v)].append(k)
        else:
            rev_B[v].append(k)

    #Sort the values of reverse dictionary
    for k, v in rev_A.items():
        rev_A[k] = sorted(v)

    for k, v in rev_B.items():
        rev_B[k] = sorted(v)

    #See if the values of both dictionaries group in same fashion
    return list(sorted(rev_A.values())) == list(sorted(rev_B.values()))

A = {'A':1, 'B':4, 'C':1}
B = {'A':9, 'B':2, 'C':9}

print(eq(A,B))

A = {'A':3, 'B':3, 'C':3, 'R':4, 'T':4}
B = {'C':8, 'R':6, 'T':6, 'A':8, 'B':8}

print(eq(A,B))

A = {'A':3, 'B':3, 'C':3, 'R':4, 'T':4}

B = {'A':[], 'B':[], 'C':[], 'R':"", 'T':""}
print(eq(A,B))

输出将是

代码语言:javascript
复制
True
True
True
票数 2
EN

Stack Overflow用户

发布于 2019-06-26 02:57:39

编辑:修正了@pault指出的问题。虽然这个特定的输入现在会引发一个错误,因为b 中的值是不可理解的.

因为OP提到他们最初的方法不会短路,所以我会尝试给出一种方法。这种方法确实要求ab中的值是可选的。

不过,我还没描述过这个。无论如何,这可能取决于输入的性质。具体来说,如果可以散列ab中的值,但是效率很低,那么这种方法当然会受到影响。

另一个想法是:如果这两个块是相等的(在这个定义下)或接近,那么这个实现需要比较python循环中的所有元素,这可能比其他实现要慢。然而,如果他们可能有很大的不同,允许短路工作,那么这种方法可能会显示出一个优势。

编辑:添加了一个参数encoding来强制散列一些对象。当然,这会产生一些副作用,这取决于所使用的编码,比如[]()被认为是相等的,而具有不同顺序的等号块被认为是不相等的。

代码语言:javascript
复制
def eq(a, b, encoding = None):
    if len(a) != len(b): return False
    mapping = {}
    value_set = set()
    for k, v_a in a.items():
        v_b = b.get(k)
        if v_b is None: return False
        if encoding: v_a, v_b = encoding(v_a), encoding(v_b)
        if v_a in mapping:
            if mapping[v_a] != v_b: return False
        elif v_b in value_set: return False
        else:
            mapping[v_a] = v_b
            value_set.add(v_b)
    return True

用法:

代码语言:javascript
复制
import json
A = {'A':3, 'B':3, 'C':3, 'R':4, 'T':4}
B = {'A':[], 'B':[], 'C':[], 'R':"", 'T':""}
print(eq(A, B, encoding = json.dumps))
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56764377

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档