keyError: 'ba' when using setDefault method

keyError: 'ba' when using setDefault method

所以我基本上是在尝试使用 setdefault 方法将字典放入字典中。

text = 'banana'
k = 2

st = {}
circ_text = text + text[:k]
for i in range(len(circ_text) - k):
    kgram = circ_text[i:i + k]
    next_char = circ_text[i + k]
    st[kgram].setdefault(next_char, 0)
    st[kgram][next_char] += 1
print(st)

我想得到这样的东西

st = {ba : {a : 1}
      an : {a : 2}
      .......
     }

出于某种原因,我收到一个 keyError:'ba'。所以我应该在执行此操作之前将 'ba' 放入 st dict 中吗?或者有没有办法以这种方式添加 'ba' 键

您从未向 st 添加新密钥,因此它是空的。

您正在尝试访问 st['ba'] 并使用它的 setdefault 方法,好像 st['ba'] 是一个字典,但 st['ba'] 不存在。

也许您想改用 st.setdefault,并为 st['ba'] 设置默认值:

st.setdefault(kgram, {})
st[kgram].setdefault(next_char, 0)
st[kgram][next_char] += 1

或:

st.setdefault(kgram, {next_char: 0})
st[kgram][next_char] += 1

您需要在两个级别都支持动态生成 dict 条目。对于这种特殊情况,对至少一个级别使用 defaultdict 可能是最简单的(并且由于您正在计算事物,所以对内部 dict 使用 Counter)。

from collections import defaultdict, Counter

text = 'banana'
k = 2

st = defaultdict(Counter)
circ_text = text + text[:k]
for i in range(len(circ_text) - k):
    kgram = circ_text[i:i + k]
    next_char = circ_text[i + k]
    st[kgram][next_char] += 1
print(st)

这简化了您的代码(没有明确处理丢失的键),尽管它确实意味着您的输出将不只是使用 {} 包装。如果你希望它看起来像最后嵌套的 dicts(and/or 需要像 defaultdictCounter 那样停止自动激活键),你可以添加:

st = {k: dict(v) for k, v in st.items()}

print 之前,这将转换回 dict 的普通 dict