简体   繁体   English

在 Python 中动态创建嵌套字典

[英]Create nested dictionary on the fly in Python

Trying to understand how to create nested dictionaries on the fly.试图了解如何即时创建嵌套字典。 Ideally my dictionary would look something like:理想情况下,我的字典看起来像:

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

Here's what i have so far:这是我到目前为止所拥有的:

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)

has the following output:有以下输出:

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'

How do you make a nested dictionary like this on the fly?您如何即时制作这样的嵌套字典?

dict.setdefault is a good tool, so is collections.defaultdict dict.setdefault是一个好工具, collections.defaultdict也是一个好工具

Your problem right now is that newdict is an empty dictionary, so newdict[msgid] refers to a non-existent key.你现在的问题是newdict是一个空字典,所以newdict[msgid]指的是一个不存在的键。 This works when assigning things ( newdict[msgid] = "foo" ), however since newdict[msgid] isn't set to anything originally , when you try to index it you get a KeyError .这在分配事物时有效( newdict[msgid] = "foo" ),但是由于newdict[msgid]最初没有设置为任何内容,当您尝试对其进行索引时,您会得到KeyError

dict.setdefault lets you sidestep that by initially saying "If msgid exists in newdict , give me its value. If not, set its value to {} and give me that instead. 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!

Using collections.defaultdict saves you the step of calling dict.setdefault .使用collections.defaultdict dict.setdefault调用dict.setdefault的步骤。 A defaultdict is initialized with a function to call that produces a container that any non-existent key gets assigned as a value, eg一个defaultdict用一个函数初始化,调用它产生一个容器,任何不存在的键都被分配为一个值,例如

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

You can use this to say "Hey if I talk to you about a new msgid, I want it to be a new dictionary.你可以用它说“嘿,如果我和你谈论一个新的 msgid,我希望它成为一个新的字典。

from collections import defaultdict

def makedict(results):
    newdict = defaultdict(dict)
    for item in results:
        msgid = re.search(r'Message \d+', item).group()
        newdict[msgid]['emails'] = ...
        newdict[msgid]['status'] = ...

Found what I was looking for in this regard at https://quanttype.net/posts/2016-03-29-defaultdicts-all-the-way-down.htmlhttps://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>, {})

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

newdict[msgid] = {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM