试图了解如何即时创建嵌套字典。理想情况下,我的字典看起来像:
mydict = { 'Message 114861156': { 'email': ['user1@domain.com', 'user2@domain.com'] }, { 'status': 'Queued mail for delivery' }} 
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止所拥有的:
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)
Run Code Online (Sandbox Code Playgroud)
有以下输出:
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'
Run Code Online (Sandbox Code Playgroud)
您如何即时制作这样的嵌套字典?
dict.setdefault 是一个好工具,也是 collections.defaultdict
你现在的问题是这newdict是一个空字典,所以newdict[msgid]指的是一个不存在的键。这在分配事物 ( newdict[msgid] = "foo") 时有效,但是由于最初newdict[msgid]未设置为任何内容,因此当您尝试对其进行索引时,您会得到一个.KeyError
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!
Run Code Online (Sandbox Code Playgroud)
使用collections.defaultdict可以节省您调用 的步骤dict.setdefault。Adefaultdict用一个函数初始化,调用它产生一个容器,任何不存在的键都被分配为一个值,例如
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
Run Code Online (Sandbox Code Playgroud)
你可以用它说“嘿,如果我和你谈论一个新的 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'] = ...
Run Code Online (Sandbox Code Playgroud)