我遍历文件并希望构建一个多级动态字典。最后一级需要存储值列表。
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)
我需要这样做,因为lvlTwoKey会在不同的valueFound中被多次找到。
不幸的是,此代码导致lvlOneKey的KeyError。我做错了什么?
答案 0 :(得分:2)
这是一种确保您不会收到错误的几乎万无一失的方法。我们定义myDict
的方式,您可以拥有字典“级别1”和字典“级别2”的任何键。默认情况下,在字典树的末尾假定一个空列表。
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)
答案 1 :(得分:1)
使用以下内容替换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)
这使用字典上的get()
方法,您可以阅读here。除此之外,它只是一个标准字典,我发现它通常比复杂的默认字典更具可读性/直观性。
答案 2 :(得分:0)
如果进一步嵌套,这会有点烦人,但使用这种模式会有效。
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]}
}