在Python中动态创建嵌套字典

时间:2016-02-19 20:17:31

标签: python dictionary

尝试了解如何动态创建嵌套词典。理想情况下,我的字典看起来像:

mydict = { 'Message 114861156': { 'email': ['user1@domain.com', 'user2@domain.com'] }, { 'status': 'Queued mail for delivery' }} 

这是我到目前为止所拥有的:

sampledata = "Message 114861156 to user1@domain.com user2@domain.com  [InternalId=260927844] Queued mail for delivery'."

makedict(sampledata)

def makedict(results):
  newdict = {}
  for item in results:
    msgid = re.search(r'Message \d+', item)
    msgid = msgid.group()
    newdict[msgid]['emails'] = re.findall(r'\w+@\w+\.\w+', item)
    newdict[msgid]['status'] = re.findall(r'Queued mail for delivery', item)

具有以下输出:

Traceback (most recent call last):
  File "wildfires.py", line 57, in <module>
    striptheshit(q_result)
  File "wildfires.py", line 47, in striptheshit
    newdict[msgid]['emails'] = re.findall(r'\w+@\w+\.\w+', item)
KeyError: 'Message 114861156'

如何动态制作这样的嵌套字典?

3 个答案:

答案 0 :(得分:2)

dict.setdefault是一个很好的工具,collections.defaultdict

也是

您现在的问题是newdict是一个空字典,因此newdict[msgid]指的是一个不存在的密钥。这在分配内容(newdict[msgid] = "foo")时有效,但由于newdict[msgid]未设置为最初的任何内容,因此当您尝试对其进行索引时,您会得到{{1} }。

KeyError让你回避这一点,最初说&#34;如果dict.setdefault中存在msgid,请告诉我它的价值。如果没有,请将其值设置为newdict并改为给我。

{}

使用def makedict(results): newdict = {} for item in results: msgid = re.search(r'Message \d+', item).group() newdict.setdefault(msgid, {})['emails'] = ... newdict[msgid]['status'] = ... # Now you KNOW that newdict[msgid] is there, 'cuz you just created it if not! 可以为您保存调用collections.defaultdict的步骤。 dict.setdefault初始化时带有一个调用函数,该函数生成一个容器,任何不存在的密钥都被赋值为一个值,例如

defaultdict

你可以用它来说&#34;嘿,如果我和你谈论一个新的msgid,我希望它是一个新词典。

from collections import defaultdict

foo = defaultdict(list)
# foo is now a dictionary object whose every new key is `list()`
foo["bar"].append(1)  # foo["bar"] becomes a list when it's called, so we can append immediately

答案 1 :(得分:0)

在将项目存储在其中之前,您需要将newdict[msgid]创建为空字典。

newdict[msgid] = {}

答案 2 :(得分:0)

https://quanttype.net/posts/2016-03-29-defaultdicts-all-the-way-down.html

找到了我在这方面寻找的东西
def fix(f):
    return lambda *args, **kwargs: f(fix(f), *args, **kwargs)

>>> from collections import defaultdict
>>> d = fix(defaultdict)()
>>> d["a"]["b"]["c"]
defaultdict(<function <lambda> at 0x105c4bed8>, {})