简体   繁体   English

如何在多级字典中附加到列表?

[英]How to append to list within multilevel dictionary?

I'm traversing through a file and want to build a dynamic dictionary of multiple levels. 我正在浏览一个文件,想要构建一个多层次的动态字典。 The last level needs to store a list of values. 最后一级需要存储值列表。

myDict = defaultdict(dict)

for key in lvlOneKeys: # this I know ahead of time so I set up my dictionary with first level. I'm not sure if this is necessary.
    myDict[key] = {}

with open(myFile, "rb") as fh:
    for line in fh:
        # found something, which will match lvlOneKey and dynamically determine lvlTwoKey and valueFound
        # ...
        myDict[lvlOneKey][lvlTwoKey].append(valueFound)

I need to do this because lvlTwoKey will be found multiple times with different valueFound's. 我需要这样做,因为lvlTwoKey会被多次找到不同的valueFound。

Unfortunately this code results in a KeyError for lvlOneKey. 不幸的是,此代码导致lvlOneKey的KeyError。 What am I doing wrong? 我究竟做错了什么?

This is an almost foolproof way of ensuring you won't get an error. 这是一种几乎万无一失的确保您不会收到错误的方法。 The way we have defined myDict , you can have any keys for dictionary "level 1" and dictionary "level 2". 我们定义myDict的方式,你可以拥有字典“level 1”和字典“level 2”的任何键。 By default, an empty list is assumed at the end of the dictionary tree. 默认情况下,在字典树的末尾假定一个空列表。

myDict = defaultdict(lambda: defaultdict(list))

with open(myFile, "rb") as fh:
    for line in fh:
        # found something, which will match lvlOneKey and dynamically determine lvlTwoKey and valueFound
        # ...
        myDict[lvlOneKey][lvlTwoKey].append(valueFound)

Replacing the code under the for loop with the following should solve your problem: 用以下内容替换for循环下的代码可以解决您的问题:

# if there is no `lvlTwoKey` in `myDict`, initialize a list with `valueFound` in it  
if not myDict[lvlOneKey].get(lvlTwoKey, None):
    myDict[lvlOneKey][lvlTwoKey] = [valueFound]
# otherwise, append to the existing list 
else: 
    myDict[lvlOneKey][lvlTwoKey].append(valueFound)

This uses the get() method on the dictionary, which you can read about here . 这使用字典上的get()方法,您可以在这里阅读。 Besides that, it's just a standard dictionary, which I find often to be more readable / intuitive than complex defaultdicts. 除此之外,它只是一个标准字典,我发现它通常比复杂的默认字典更具可读性/直观性。

This can get a bit annoying if you get much further nested, but using this pattern will work. 如果你进一步嵌套,这可能会有点烦人,但使用这种模式将起作用。

l1keys = [1, 2, 1]
l2keys = ['foo', 'bar', 'spangle']

base = {}
for l1key, l2key in zip(l1keys, l2keys):
    for i in range(5):
        l1 = base.get(l1key, {})
        l2 = l1.get(l2key, [])
        l2.append(i)
        l1[l2key] = l2
        base[l1key] = l1

assert base == {
    1: {'foo': [0, 1, 2, 3, 4], 'spangle': [0, 1, 2, 3, 4]},
    2: {'bar': [0, 1, 2, 3, 4]}
}

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

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