【问题标题】:Dictionary changing size during iteration and I don't know why字典在迭代期间改变大小,我不知道为什么
【发布时间】:2017-07-16 02:48:15
【问题描述】:

这是错误信息:

RuntimeError: 迭代期间字典大小改变

这是我的代码段(

# Probability Distribution from a sequence of tuple tokens
def probdist_from_tokens (tokens, N, V = 0, addone = False):
    cfd = ConditionalFreqDist (tokens)
    pdist = {}

    for a in cfd:  # <= line with the error
        pdist[a] = {}
        S = 1 + sum (1 for b in cfd[a] if cfd[a][b] == 1)
        A = sum (cfd[a][b] for b in cfd[a])

        # Add the log probs.
        for b in cfd[a]:
            B = sum (cfd[b][c] for c in cfd[b])
            boff = ((B + 1) / (N + V)) if addone else (B / N)
            pdist[a][b] = math.log ((cfd[a][b] + (S * boff)) / (A + S))

        # Add OOV for tag if relevant
        if addone:
            boff = 1 / (N + V)
            pdist[a]["<OOV>"] = math.log ((S * boff) / (A + S))

    return pdist

我基本上只是使用 cfd 作为参考,将正确的值放入 pdist。我不是想改变 cfd,我只是想迭代它的键和它的子字典的键。

我认为问题是由我设置变量 A 和 B 的行引起的,当我在这些行上有不同的代码时,我得到了同样的错误,但是当我用常量值替换它们时我没有得到错误.

【问题讨论】:

  • 你能提供一个独立的例子来说明这个问题吗?

标签: python python-3.x dictionary nltk


【解决方案1】:

nltk.probability.ConditionalFreqDist继承defaultdict,这意味着如果你读取一个不存在的条目cfd[b],一个新的条目(b, FreqDist())将被插入到字典中,从而改变它的大小。问题演示:

import collections
d = collections.defaultdict(int, {'a': 1})
for k in d:
    print(d['b'])

输出:

0
Traceback (most recent call last):
  File "1.py", line 4, in <module>
    for k in d:
RuntimeError: dictionary changed size during iteration

所以你应该检查这一行:

    for b in cfd[a]:
        B = sum (cfd[b][c] for c in cfd[b])

您确定b 密钥确实存在于cfd 中吗?您可能需要将其更改为

        B = sum(cfd[b].values()) if b in cfd else 0
#                                ^~~~~~~~~~~

【讨论】:

    猜你喜欢
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 2023-04-02
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多