【问题标题】:How to check if a dictionary is invertible如何检查字典是否可逆
【发布时间】:2019-11-08 14:09:29
【问题描述】:

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

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'} 应该是 True 时,它会返回 False。我确定make_inv_dict 函数存在问题;仅仅是因为adictadict = make_inv_dict(adict) 中不是一个合适的变量名吗?还是函数返回错误结果的其他原因?

【问题讨论】:

  • 您可以简单地使用len(set(adict.values())) == len(adict)检查字典是否可逆。

标签: python dictionary inverse


【解决方案1】:

你给出的函数至少存在三个问题:

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

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


我猜有些人在寻找正确的方法来反转字典时会发现这个问题,所以这里有一个:如果可能,此函数返回反转字典,否则返回 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

【讨论】:

    【解决方案2】:

    我的回答:

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

    【讨论】:

    • 在执行 len 之前无需将集合转换为列表 - 编写 len(set(...)) 时效果非常好(而且速度更快)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-08
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    • 2017-02-27
    • 1970-01-01
    • 2014-10-03
    相关资源
    最近更新 更多