【问题标题】:inverting a dictionary in Python在 Python 中反转字典
【发布时间】:2021-08-21 20:29:33
【问题描述】:

这是一个反转字典的代码,但为了理解 定义的函数 invert_dict(dic) 中每个代码元素的作用,我遇到了一些麻烦,如果有人把它分解给我,并向我解释每个元素的使命。 谢谢。

animals = {'Lion':["meet", 1.2 ,'yellow'],'Cat':["milk", 0.3,'white'],'dog':["Dog", 1,'black']}

def invert_dict(dic):
    return {v: d.setdefault(v, []).append(k) or d[v] for d in ({},) for k in dic for v in dic[k]}

print(invert_dict(animals))

输出:

{'meet': ['Lion'], 1.2: ['Lion'], 'yellow': ['Lion'], 'milk': ['Cat'], 0.3: ['Cat'], 'white': ['Cat'], 'Dog': ['dog'], 1: ['dog'], 'black': ['dog']}

【问题讨论】:

    标签: python dictionary


    【解决方案1】:

    听起来像是 defaultdict 的经典用法

    animals = {'Lion':["meet", 1.2 ,'yellow'],'Cat':["milk", 0.3,'white'],'dog':["Dog", 1,'black']}
    
    from collections import defaultdict
    def invert_dict(d):
        ret = defaultdict(list)
        d = [(v,k) for k, lst in d.items() for v in lst]
        for k,v in d.items():
            ret[k].append(v)
        return dict(ret)
    

    【讨论】:

      【解决方案2】:
      {v: d.setdefault(v, []).append(k) or d[v] for d in ({},) for k in dic for v in dic[k]}
      

      让我们从右边分解一下

      for k in dic for v in dic[k]
      

      使用带有值的字典作为列表{ k: [v1, v2] },并提取对应的键为kv = [v1, v2]中的值列表

      v: d.setdefault(v, []).append(k) or d[v] for d in ({},)
      

      for v in dic[k] 循环每个键的值,即[v1, v2],并使用defaultdict 来标识结果字典中已经存在的值,如果存在,它将原始字典中的键附加到新字典中产生的倒排字典。如果没有,它会分配密钥。

      对于一个样本{ k: [v1, v2, v3], z: [v1] },每次运行后,倒排字典的状态如下:

      {}
      { v1 : [k] }
      { v1 : [k], v2 : [k] }
      { v1 : [k], v2 : [k], v3: [k] }
      { v1 : [k, z], v2 : [k], v3: [k] }  # because v1 already exists, z is appended
      

      这相当于:

      from collections import defaultdict
      
      def invert_dict_exploded(dic):
          d = defaultdict(list)
          for key in dic:
              for value in dic[key]:
                  d[value].append(key)
          return dict(d)
      

      【讨论】:

        【解决方案3】:

        我们需要按顺序,从外到内:

        • 大括号和冒号表示法
        • For 循环
        • 附加

        大括号

        大括号在 Python 中用于创建字典或集合。在这种情况下,它们用于创建字典,因为我们有 {key: value} 符号。在本次讨论中,我们称其为“返回的字典”。

        For 循环

        这些 for 循环相当于:

        for d in ({},):
            for k in dic:
                for v in dic.values():
                    ...
        

        这是一种速记符号,可以方便地快速创建集合。当它没有被滥用时,它通常是非常可读的。

        for d in ({},) 仅用于声明一个字典,该字典将在迭代键和值时坐在那里(因为正如我们在上面看到的,它位于最外层循环中)。字典名为d

        附加

        对于每个键/值对,我们使用冒号表示法在返回的字典中创建一个新键,其中键实际上是输入值之一,然后我们做两件事:

        1. 在我们的 d 字典中添加一个项目,该字典始终是一个列表
        2. 将列表分配给给定的键

        如果在字典中没有找到键 vk.setdefault(v, []) 位将设置默认值 [],然后将返回该列表(新创建的空列表或在该键处找到的列表),这然后由.append(k) 位使用,将键作为值附加到该列表中。这会处理输入列表中具有相同值的项目的情况,并将该值的所有键收集在一起,例如:

        animals = {'Lion':["meet", 1.2 ,'yellow'],'Cat':["milk", 0.3,'black'],'dog':["Dog", 1,'black']}
        

        您可以在其中看到包含“黑色”项目的多个列表,并将输出以下内容:

        {'meet': ['Lion'], 1.2: ['Lion'], 'yellow': ['Lion'], 'milk': ['Cat'], 0.3: ['Cat'], 'black': ['Cat', 'dog'], 'Dog': ['dog'], 1: ['dog']}
        

        请注意,“Cat”和“dog”键都被添加到结果中的“black”列表中。

        最后,部分。 list.append() 函数总是返回 None,因为每个没有显式返回的函数都会在 Python 中自动返回 None

        or 运算符用于短路表达式。它被写成A or B 并且被读作“如果 A 的计算结果为真值,则表达式的计算结果为 A;如果 A 的计算结果为假值,则表达式的计算结果为 B”。 None 总是以布尔形式计算为 false,因此表达式 d.setdefault(v, []).append(k) or d[v] 总是计算为 d[v],但仅在执行 setdefault()append() 之后。

        v: d.setdefault(v, []).append(k) or d[v] 因此可以读作:

        在我们的返回的字典中创建一个键v;如果v不是d的键,则设置d[v] = [];将k的值附加到d[v],并将d[v]设置为v的值。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-01-11
          • 2011-03-25
          • 2021-01-24
          • 2019-04-09
          • 1970-01-01
          • 1970-01-01
          • 2023-04-06
          相关资源
          最近更新 更多