You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python defaultdict使用字符串键时的异常行为原因咨询

问题背景
  • 如果该问题此前已有相关解答还望见谅,我很难用一句话描述清楚该场景,因此此前搜索未找到有效结果。
  • 我在尝试解决LeetCode 1048 最长字符串链问题,自认为代码逻辑通顺,但实际运行结果始终不符合预期。
  • 调试时我发现一个反常现象:只要在循环中加入访问dp[newWord]的语句(哪怕只是写一句不做任何输出和计算的dp[newWord]),代码就能输出正确结果,否则始终返回错误值。
  • 我此前大量使用过defaultdict,从未遇到过这类问题,希望知道该现象的成因。

对应的问题代码如下:

import collections

def longestStrChain(words):
    words.sort(key=lambda word: (len(word), word))
    dp = collections.defaultdict(int)
    result = 1
    
    for word in words:
        if len(word) == 1:
            dp[word] = 1
        else:
            for i in range(len(word)):
                newWord = str(word[:i] + word[i+1:])
                # dp[newWord] # 取消注释这行代码就能正常运行
                if newWord in dp:
                    dp[word] = max(dp[word], dp[newWord] + 1)
                    result = max(result, dp[word])
                else:
                    dp[word] = 1
                
    return result

print(longestStrChain(["a","b","ba","bca","bda","bdca"]))
# 预期输出4,不取消注释时始终返回3
问题成因

这根本不是defaultdict的特殊玄学行为,是两个逻辑错误叠加导致的巧合:

  1. 初始值赋值位置错误
    你把dp[word] = 1的初始值赋值写在了删除字符的循环内部,只要某一个删除位置得到的newWord不在dp里,就会把之前循环迭代算出来的更长的链长度直接覆盖成1。
    以测试用例里的最长词bdca为例,循环到删除最后一个字符得到bdc时,bdc不在dp中,就会触发else分支,把之前算好的dp["bdca"] = 4直接重置成1,最终返回结果自然不对。

  2. 提前访问dp[newWord]刚好歪打正着屏蔽了上面的bug
    defaultdict的核心特性是:只要访问不存在的key,就会自动用默认值初始化该key并插入字典。你加的那句dp[newWord]在if newWord in dp判断之前执行,等于不管newWord之前是否存在,访问之后它必然已经在dp里了,else分支永远不会触发,自然也就不会出现循环内重置dp[word]为1的问题,代码看起来就"正常运行"了。

修复方案

把dp[word]的初始值赋值移到循环外面,不要在遍历删除位置的循环里重置它即可:

import collections

def longestStrChain(words):
    words.sort(key=lambda word: len(word))
    dp = collections.defaultdict(int)
    result = 1
    
    for word in words:
        dp[word] = 1 # 每个词的初始链长只在这里设置一次
        for i in range(len(word)):
            newWord = word[:i] + word[i+1:]
            if newWord in dp:
                dp[word] = max(dp[word], dp[newWord] + 1)
                result = max(result, dp[word])
                
    return result

内容的提问来源于stack exchange,提问作者Breezy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 01:48:15