【问题标题】:Handle dictionary collision in python3在python3中处理字典冲突
【发布时间】:2020-04-30 16:56:03
【问题描述】:

我目前的以下代码工作正常:

有人可以帮我解决字典中有两个具有相同数字的键造成的冲突吗?

我尝试了多种方法(此处未列出)尝试创建一个数组来处理它,但我的方法仍然不成功。

我正在使用#python3.7

def find_key(dic1, n):
    '''
    Return the key '3' from the dict
    below.
    '''
    d = {}
    for x, y in dic1.items():
        # swap keys and values
        # and update the result to 'd'
        d[y] = x
    try:
        if n in d:
            return d[y]
    except Exception as e:
        return (e)

dic1 = {'james':2,'david':3}
# Case to test that return ‘collision’
# comment 'dic1' above and replace it by
# dic1 below to create a 'collision'
# dic1 = {'james':2,'david':3, 'sandra':3}
n = 3
print(find_key(dic1,n))

任何帮助将不胜感激。

【问题讨论】:

  • 具有相同数据的两个键本身并不是真正的冲突......这根本不是 dicts 的工作方式。冲突是指两个不同键的哈希值相同。对 dict 进行线性循环对我来说也没有多大意义——你能澄清你想要实现的目标吗?谢谢!
  • 问题的答案取决于发生碰撞时您想要做什么。是否要获取所有具有指定值的键?
  • 这不是冲突,但是如果您进行反向查找字典,那将是冲突。或者,您可以让您的函数返回一个生成器,该生成器生成所有具有匹配值的键。
  • @KennyOstrom 是的,或者列表理解。并注意它们会产生碰撞,因为它们确实会创建反向字典...
  • find_key(dic1,n)应该返回什么? 'david''sandra',是其中之一,还是两者都有?注意,在你的函数中创建一个反向字典来获取一个键是毫无意义的。

标签: python python-3.x dictionary hashtable collision


【解决方案1】:

您知道应该有多次退货,因此请提前做好计划。

def find_keys_for_value(d, value):
    for k, v in d.items():
        if v == value:
            yield k

data = {'james': 2, 'david': 3, 'sandra':3}
for result in find_keys_for_value(data, 3):
    print (result)

【讨论】:

    【解决方案2】:

    您可以使用defaultdict

    from collections import defaultdict
    
    def find_key(dct, n):
        dd = defaultdict(list)
        for x, y in dct.items():
            dd[y].append(x)
        return dd[n]
    
    dic1 = {'james':2, 'david':3, 'sandra':3}
    print(find_key(dic1, 3))
    print(find_key(dic1, 2))
    print(find_key(dic1, 1))
    

    输出:

    ['david', 'sandra']
    ['james']
    []
    

    但是,只有在给定不同值的情况下重复搜索相同 dict 的键时,才可以从所有键和值构建 defaultdict。否则,肯尼奥斯特罗姆的方法是可取的。无论如何,如果保持现状,上述内容几乎没有意义。

    如果您对生成器和 yield 不满意,这里是 Kenny Ostrom 转换为列表的方法(效率低于生成器,但比上述一次性搜索要好):

    def find_key(dct, n):
        return [x for x, y in dct.items() if y == n]
    

    输出同上。

    【讨论】:

    • 正是我想要的。谢谢@waltertross
    • 如果数据没有变化,并且你需要做很多次查找和反向查找,那么你应该构建这个反向查找字典一次,并保留它。 O(1) 查找,O(1) 反向查找,增加了更改的代码和时间复杂度,但如果您的数据不经常更改,这并不重要。
    猜你喜欢
    • 2017-06-25
    • 2016-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多