从字符串[Python]创建多级字典

时间:2012-02-06 05:11:00

标签: python loops dictionary

我正在为我的一个网络服务创建一个邮件“bot”,它会定期收集一个从PHP脚本发送的电子邮件队列,并通过Google的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 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

你错了。所以你必须检查密钥是否存在。如果在'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

注意最后一行的嵌套列表的额外括号。

答案 2 :(得分: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:])

答案 3 :(得分:0)

只检查是否存在密钥,如果不存在,则创建密钥, 如果它存在,则将数据附加到现有列表。

if(messsage[0] in merged):
     merged[message[0]] = [message[1],[message[2]]
else:
     merged[message[0]].append([[message[1], message[2]])