如何检查字典是否可逆

How to check if a dictionary is invertible

我正在研究一个问题,该问题需要指出确定字典是否可逆(对于字典中出现的每个值,只有一个键映射到该值)的函数中的问题.问题如下:

def is_invertible(adict):
    inv_dict = make_inv_dict(adict)
    return adict == inv_dict

def make_inv_dict(adict):
    if len(adict) > 0:
       key, val = adict.popitem()
       adict = make_inv_dict(adict)
       if val not in adict.values():
          adict[key] = val
       return adict
    else:
        return {}

目前,{'a': 'b', 'b': 'e', 'c': 'f'} 的 returns False 本应是 True。我确定 make_inv_dict 函数有问题;仅仅是因为 adictadict = make_inv_dict(adict) 中不是一个合适的变量名吗?还是函数 returns 出现错误结果的另一个原因?

您提供的函数至少存在三个问题:

  1. 条件adict == inv_dict检查字典是否它自己的逆,而不仅仅是它是可逆的。
  2. 它使用pop_item从输入字典中删除一对key/value,然后将其向后插入,因此该函数就地运行。等到完成的时候,adict原来的内容就被彻底破坏了,反正比较也没有意义了。
  3. adict[key] = val按原顺序插入key/value对;逆序应该是adict[val] = key。所以这个函数并没有像它的名字所承诺的那样做一个逆向字典。

需要注意的是,如果不是字典(2.)被破坏,错误(1.)和(3.)就会抵消,因为函数的结果是重建原来的字典但没有重复值。


我猜有些人如果正在寻找一种正确的字典反转方法,他们会发现这个问题,所以这里有一个:这个函数 returns 如果可能的话,反转字典,或者 None 否则。

def invert_dict(d):
    out = dict()
    for k,v in dict.items():
        if v in out:
            return None
        out[v] = k
    return out

返回字典是否可逆的布尔值的辅助函数:

def is_invertible(d):
    return invert_dict(d) is not None

我的回答:

def is_invertible(dict_var):
    return len(dict_var.values()) == len(set(dict_var.values()))