在字典和列表比较字符时出现Python KeyError

-1 投票
3 回答
1114 浏览
提问于 2025-04-18 06:25

我遇到了一个问题,涉及到在一个字典里的字符键和一个列表中的字符进行比较。

我的任务是读取一段文本,并统计所有开头的字母。

我有一个包含字符的列表:

bchars = ('i','g','h','n','h')

还有一个字典,里面有字母和它们的频率,初始值都是零:

d = dict(dict())
  for i in range(97,123):
    d[i-97]={chr(i):0}

现在我想这样检查:

for i in range(len(bchars)):
  for j in range(len(d)):
    if(bchars[i] in d[j]):
      d[j][chr(i+97)] +=1
    else:
      d[j][chr(i+97)] +=0

也就是说,如果列表中的字符在某个位置是字典的键,就加1;如果不是,就加零。我原以为用if/else语句可以避免出现KeyError(键错误)。

有没有更优雅的解决办法呢?

3 个回答

1
from collections import Counter

bchars = ('i','g','h','n','h')
counts = Counter(bchars)
print(counts)
print(counts['h']) 

打印

Counter({'h': 2, 'i': 1, 'g': 1, 'n': 1})
2
1

这个嵌套字典似乎没有必要:

d = [0] * 26
for c in bchars:
    d[ord(c)-97] += 1

你可能还想看看collections模块里的Counter类。

1

具体的问题是,你在检查 bchars[i] 是否在 d[j] 中,但你实际上使用的键是 chr(i+97)

chr(i+97)bchars 中第 i 个字符的索引,但它是从 ASCII 字符 'a' 开始映射的。你为什么想用这个作为你的键呢?

我觉得你真正想做的是:

for i in range(len(bchars)):
    for j in range(len(d)):
        if(bchars[i] in d[j]):
            d[j][bchars[i]] += 1
        else:
            d[j][bchars[i]] = 1

注意,在 else 中你不能使用 +=; 记得你 刚刚检查过 这个键是否存在,并决定它不存在吗?

更广泛地说,你的代码不太合理 - 它过于复杂,并没有真正利用 Python 字典的强大功能。 d 看起来像:

{0: {'a': 0}, 1: {'b': 0}, 2: {'c': 0}, ...}

直接建立一个字符到计数的字典会更合理:

{'a': 0, 'b': 0, 'c': 0, ...}

这样你就可以简单地做:

for char in bchars:
    if char in d:
        d[char] += 1

Python 甚至有一个 专门用于处理这种事情的类

撰写回答