从字符串创建多层字典 [Python]
我正在为我的一个网络服务创建一个邮件“机器人”,这个机器人会定期收集要发送的电子邮件队列,然后通过谷歌的SMTP服务器发送这些邮件。我的PHP脚本返回的邮件格式是这样的:
test@example.com:Full Name:shortname\ntest2@example.com:Another Full Name:anothershortname\ntest@example.com:Foo:bar
我需要把它“转换”成像这样的格式:
{
"test@example.com": [
[
"Full Name",
"shortname"
],
[
"Foo",
"bar"
]
],
"test2@example.com": [
[
"Another Full Name",
"anothershortname"
]
]
}
注意,我每封邮件只需要一个键,即使同一个地址出现多次。我知道我可能可以用两个连续的循环来实现,一个循环用来建立字典的第一层,另一个循环用来填充它,但我觉得应该有办法一次性完成。这是我目前的代码:
raw = "test@example.com:Full Name:shortname\ntest2@example.com:Another Full Name:anothershortname\ntest@example.com:Foo:bar"
print raw
newlines = raw.split("\n")
print newlines
merged = {}
for message in newlines:
message = message.split(":")
merged[message[0]].append([message[1], message[2]])
print merged
在循环的最后一行,我遇到了一个KeyError错误,我理解为在向某个键添加内容之前,这个键必须先存在(如果尝试向一个不存在的键添加内容,是不会创建这个键的)。
我对Python还很陌生,对列表和字典也不太熟悉,所以非常感谢你的帮助!
4 个回答
1
我看到你已经接受了一个答案,但也许你还是会对你正在做的事情感兴趣,其实可以很简单地用 defaultdict
来实现:
from collections import defaultdict
raw = "test@example.com:Full Name:shortname\ntest2@example.com:Another Full Name:anothershortname\ntest@example.com:Foo:bar"
merged = defaultdict(list)
for line in raw.split('\n'):
line = line.split(':')
merged[line[0]].append(line[1:])
1
可能的用法是:
for message in newlines:
message = message.split(":")
temp = []
temp.append(message[1])
temp.append(message[2])
merged[message[0]] = temp
实际上可能是:
for message in newlines:
message = message.split(":")
temp = []
temp.append(message[1])
temp.append(message[2])
if message[0] not in merged:
merged[message[0]] = []
merged[message[0]].append(temp)
0
你说得对,确实有错误。所以你需要检查一下这个键是否存在。'key' in dict
这个表达式会返回 True
,如果 'key'
在 dict
里找到了的话;如果没找到,就返回 False
。根据这个思路,下面是你的完整代码(去掉了调试用的打印语句):
raw = "test@example.com:Full Name:shortname\ntest2@example.com:Another Full Name:anothershortname\ntest@example.com:Foo:bar"
newlines = raw.split("\n")
merged = {}
for message in newlines:
message = message.split(":")
if message[0] in merged:
merged[message[0]].append([message[1], message[2]])
else:
merged[message[0]]=[[message[1], message[2]]]
print merged
注意倒数第二行的嵌套列表多了个括号。