在Python中动态创建嵌套字典

在Python中动态创建嵌套字典,python,dictionary,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 [Inter

试图了解如何动态创建嵌套字典。理想情况下,我的字典应该是:

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'
回溯(最近一次呼叫最后一次):
文件“wildfires.py”,第57行,在
条带点击(q_结果)
文件“wildfires.py”,第47行,在striptheshit中
newdict[msgid]['emails']=re.findall(r'\w+@\w+\.\w+',项)
KeyError:“消息114861156”

如何在运行时制作这样的嵌套词典

您需要先创建
newdict[msgid]
作为空字典,然后再将项目存储在其中

newdict[msgid] = {}

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

您现在的问题是
newdict
是一个空字典,因此
newdict[msgid]
引用了一个不存在的键。这在分配内容时起作用(
newdict[msgid]=“foo”
),但是由于
newdict[msgid]
最初没有设置为任何内容,因此当您尝试为其编制索引时,您会得到一个
keyrerror


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
,该函数生成一个容器,将任何不存在的键指定为值,例如

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
你可以用它来表示“嘿,如果我和你谈论一个新的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'] = ...

除非
newdict[msgid]
已经存在,否则您将删除数据。在itFYI中存储项目之前,合法的电子邮件地址可以匹配比
r'\w+@\w+\.\w+'
多得多的模式。如果您不在受约束的环境中(所有电子邮件地址都在某个公司域中),那么这个正则表达式就不好。您可以(它包括一个“大部分足够”的正则表达式和一个符合RFC的疯狂正则表达式)。