Python自定义SortedDict类时为何字典属性被识别为列表引发索引报错
问题原因
报错的核心原因是_sort()方法的实现错误,直接把self.map从字典类型覆盖成了列表类型:
- Python内置
sorted()函数的返回值永远是排序后的列表,不会保留传入参数的原始类型。 - 直接对字典做迭代时,默认只会遍历字典的键,因此执行
self.map = sorted(self.map)时,本质是把字典所有键取出来排序生成列表,再赋值给self.map,原本存储的键值对会全部丢失。 - 你的
__init__方法执行顺序是先把self.map初始化为传入键值对组成的字典,再立刻调用_sort(),所以初始化完成后self.map就已经变成了键组成的排序列表。这也解释了你观察到的现象:在_sort()调用前打印self.map是字典,后续所有方法中访问self.map都是列表类型。
你可以用简单代码验证这个逻辑:
demo_dict = {"test1":1, "test2":2, "a":2, "b":3} print(type(sorted(demo_dict))) # 输出 <class 'list'> print(sorted(demo_dict)) # 输出 ['a', 'b', 'test1', 'test2'],仅包含键
此时你用字符串键去索引列表,自然会抛出TypeError: list indices must be integers or slices, not str的错误。
修复方法
修改_sort()方法的逻辑,排序时保留键值对,最终返回排序后的字典即可:
def _sort(self): # 取字典的(键,值)元组列表排序,再转回字典 self.map = dict(sorted(self.map.items()))
如果要让类的行为更符合字典的使用习惯,还可以补充几个细节:
- 在
__setitem__方法末尾调用self._sort(),保证每次新增/修改键值对后字典始终保持有序 - 把自定义的
contains方法重命名为__contains__,这样就可以直接用key in 实例的语法做成员判断 - 根据需要补充
__delitem__、__iter__、__len__等双下方法,对齐原生字典的接口行为
内容的提问来源于stack exchange,提问作者lotkey
相关产品推荐
相关产品推荐

