【问题标题】:Finding a list of keys containing equal values in a dictionary在字典中查找包含相等值的键列表
【发布时间】:2019-12-23 16:58:01
【问题描述】:

我想在字典中查找包含与其他元素相等的值的所有键的列表。

例如:

dict_with_dups = {
    "a": 1,
    "b": 1,
    "c": 1,
    "d": 2,
    "e": 3,
    "f": 3,
    "g": 4,
}

keys_with_same = locate_same_keys(dict_with_dups)

for key_list in keys_with_same:
    print(f"{key_list}")

上面应该打印这个:

['a', 'b', 'c']
['e', 'f']

如何最有效地编写函数locate_same_keys

【问题讨论】:

  • 如果您尝试解决它,您将更有可能获得帮助!
  • 当您尝试编写该函数时遇到了什么问题(高效与否)?
  • 尝试阅读一些关于reversing a dict的各种问题

标签: python dictionary


【解决方案1】:

您可以使用翻转字典从字典中查找重复值。

您可以通过迭代原始字典并将每个值作为键添加到翻转字典中来创建它,并且它是键作为它的值。然后,如果该值再次出现在原始字典中,则将其键添加为翻转字典中的另一个值。

然后你可以遍历翻转字典中的每个键,检查它是否有超过 1 个值,如果是,打印它:

dict_with_dups = {
    "a": 1,
    "b": 1,
    "c": 1,
    "d": 2,
    "e": 3,
    "f": 3,
    "g": 4,
}

# finding duplicate values from dictionary using flip 
flipped = {} 

# iterate over the original dictionary and check if each value is associated 
# with more than one key
for key, value in dict_with_dups.items(): 
    if value not in flipped: 
        flipped[value] = [key] 
    else: 
        flipped[value].append(key) 

# printing all values that are assosiated with more then one key
for key, value in flipped.items():
    if len(value)>1:
        print(value)

输出

['a', 'b', 'c']
['e', 'f']

关于效率,创建翻转字典需要遍历原始字典中的所有键、值对,因此我们得到O(n) 时间复杂度。

【讨论】:

  • 更多的pythonic是使用defaultdict而不是使用这样的if ... else构造。
  • @GrzegorzBokota 我同意。但是,我认为翻转字典的解决方案更容易理解。
【解决方案2】:

遍历 dict 项并为每个值添加键到正确的列表。

from collections import defaultdict

res = defaultdict(list)

for k, v in dict_with_dups.items():
    res[v].append(k)

for v in res.values():
    if len(v) > 1:
        print(v)

【讨论】:

    【解决方案3】:
    dict_with_dups = {
        "a": 1,
        "b": 1,
        "c": 1,
        "d": 2,
        "e": 3,
        "f": 3,
        "g": 4,
    }
    result = {}
    for val in dict_with_dups:
        if dict_with_dups[val] in result:
            result[dict_with_dups[val]].append(val)
        else:
            result[dict_with_dups[val]] = [val]    
    
    for key, value in result.items():
       if len(value)>1:
          print(value)
    

    它将为您提供所有具有相同键的列表

    【讨论】:

    • 您的输出不是所要求的。
    【解决方案4】:
    dict_with_dups = {
        "a": 1,
        "b": 1,
        "c": 1,
        "d": 2,
        "e": 3,
        "f": 3,
        "g": 4,
    }
    
    result = list(filter(lambda z: len(z)>1,
                         (list(map(lambda y: y[0],
                                   filter(lambda x: x[1]==v, dict_with_dups.items())))
                          for v in set(dict_with_dups.values()))))
    

    result = [z for z in ([x[0] for x in dict_with_dups.items() if x[1]==v]
                          for v in set(dict_with_dups.values()))
              if len(z)>1]
    

    正如@wjandrea 所建议的那样。

    对我来说,第一个变体更清晰(但不太简洁)。

    【讨论】:

    • list(filter(lambda?改用列表理解 - 它更具可读性:[z for z in ... if len(z)>1]。对于list(map(lambda,请改用生成器表达式:(y[0] for y in ...)
    • 转念一想,我认为分两步完成会更清晰:映射、过滤。 (不是吹毛求疵,只是大声思考。)
    猜你喜欢
    • 2015-07-04
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-14
    • 2016-09-23
    • 1970-01-01
    • 2018-08-02
    相关资源
    最近更新 更多