Python字典列表赋值报错:为何一行写法出错两行写法正常?
字典默认值与列表append的行写法差异
核心问题出在列表的append()方法返回值是None,这和数字加法的行为完全不同:
数字加法的可行逻辑
d['a'] = d.get('a',0) + 1
这里d.get('a',0)+1会计算出一个新的数值(比如原先是0就变成1),最后把这个计算结果赋值给d['a'],整个流程是「计算新值→赋值」,逻辑通顺。
错误一行写法的问题
d['a'] = d.get('a',[]).append(1)
- 第一步
d.get('a',[])确实能拿到目标列表(字典里有'a'就取已有列表,没有就创建空列表) - 但调用
append(1)时,这个方法是原地修改列表(直接在原列表里加元素),它的返回值不是修改后的列表,而是None - 最后你把
append()返回的None赋值给了d['a'],这就导致字典里的'a'对应的值变成了None,后续操作自然会报「None type don't have append()」的错误。 - 额外说明:如果是新创建的空列表,
append(1)修改的是那个临时创建的列表,但因为没把它存到字典里,最后字典里还是存了None,等于白忙活。
两行写法为什么正常
d['a'] = d.get('a',[]) d['a'].append(1)
- 第一行:把
d.get('a',[])拿到的列表(已有或空)赋值给d['a'],让字典的'a'键明确指向这个列表对象 - 第二行:直接对字典里的这个列表对象做原地修改,因为列表是可变对象,修改后字典里的内容会自动更新,而且
append()返回的None不会被存到字典里,完全避开了赋值None的问题。
更简洁的一行替代写法
如果想实现一行操作,可以用dict.setdefault()方法,它会自动把默认值设置到字典中并返回该值:
d.setdefault('a', []).append(1)
这个写法和两行代码的逻辑一致,既完成了默认值设置,又能直接修改列表,不会出现None赋值的问题。
内容的提问来源于stack exchange,提问作者Anonymous Raze
相关产品推荐
相关产品推荐

