如何解决在 Python 中反转字典
这是一个反转字典的代码,但为了理解定义的函数 invert_dict(dic) 中每个代码元素的作用,我遇到了一些麻烦,如果有人将它分解给我并向我解释每个元素的任务。 谢谢。
{'meet': ['Lion'],1.2: ['Lion'],'yellow': ['Lion'],'milk': ['Cat'],0.3: ['Cat'],'white': ['Cat'],'Dog': ['dog'],1: ['dog'],'black': ['dog']}
输出:
private int _disposed;
private readonly string _fromEmail;
private readonly SmtpClient _client;
public Emailer()
{
_disposed = 0;
_fromEmail = "email";
_client = new SmtpClient("domain-com.mail.protection.outlook.com",25)
{
EnableSsl = true,Credentials = new NetworkCredential(_fromEmail,"password")
};
}
public async Task SendEmailAsync(IList<string> to,string subject,string body)
{
using (MailMessage mail = new MailMessage())
{
mail.From = new MailAddress(_fromEmail);
foreach (string toEmail in to)
mail.To.Add(toEmail);
mail.Subject = subject;
mail.Body = body;
mail.IsBodyHtml = true;
using (SmtpClient smtp = _client)
{
smtp.Credentials = _client.Credentials;
smtp.EnableSsl = _client.EnableSsl;
await smtp.SendMailAsync(mail);
}
}
}
解决方法
听起来像 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)
,
{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,)
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],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)
,
我们需要按顺序从外到内:
- 大括号和冒号符号
- For 循环
- 附加或值
大括号
大括号在 Python 中用于创建字典或集合。在这种情况下,它们用于创建字典,因为我们有 {key: value} 符号。在本次讨论中,我们称其为“返回的字典”。
For 循环
这些 for 循环相当于:
for d in ({},):
for k in dic:
for v in dic.values():
...
这是一种速记符号,可以方便地快速创建集合。当它没有被滥用时,它通常是非常可读的,比如在这种情况下,被滥用。
for d in ({},)
仅用于声明一个字典,该字典在迭代键和值时将位于那里(因为正如我们在上面看到的,它位于最外层循环中)。字典名为 d
。
附加或值
对于每个键/值对,我们通过使用冒号符号在返回的字典中创建一个新键,其中键实际上是输入值之一,然后我们做两件事:
- 在我们的 d 字典中添加一个项目,它始终是一个列表
- 将列表分配给给定的键
如果在字典中没有找到键 k.setdefault(v,[])
,[]
位将设置默认值 v
,然后将返回该列表(新创建的空列表或找到的列表)在那个键上),然后 .append(k)
位使用它来将键作为值附加到该列表中。这会处理输入列表中具有相同值的项目的情况,将所有键收集在一起以获得该值,例如:
animals = {'Lion':["meet",'black'],'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] = []
;将值 d[v]
附加到 k
并将 d[v]
设置为 v
的值。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。