在 Python 中反转字典
Posted
技术标签:
【中文标题】在 Python 中反转字典【英文标题】:inverting a dictionary in 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']
【问题讨论】:
【参考方案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]
,并提取对应的键为k
和v = [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
。
附加或值
对于每个键/值对,我们使用冒号表示法在返回的字典中创建一个新键,其中键实际上是输入值之一,然后我们做两件事:
-
在我们的 d 字典中添加一个项目,该字典始终是一个列表
将列表分配给给定的键
如果在字典中没有找到键 v
,k.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
的值。
【讨论】:
以上是关于在 Python 中反转字典的主要内容,如果未能解决你的问题,请参考以下文章