operator.attrgetter与itemgetter适用场景、差异及字典排序报错咨询
搞懂operator.attrgetter()和operator.itemgetter():适用场景&差异
嘿,这个问题其实挺典型的,我来给你掰扯清楚这俩工具的区别,以及什么时候该用哪个~
核心差异一句话总结
operator.itemgetter(key):给可索引/可映射对象用的,比如字典、列表、元组,它本质是调用对象的__getitem__()方法(也就是你平时用obj[key]的方式)。operator.attrgetter(attr):给类实例对象用的,用来获取对象的属性,本质是调用obj.attr这种点语法的逻辑。
各自的适用场景
用itemgetter()的情况
- 处理字典列表:就像你例子里的场景,按字典的某个键来排序,必须用这个。
- 处理嵌套列表/元组:比如想按子列表的第2个元素排序,或者按元组的第1个元素排序。
- 任何支持
[]索引取值的对象,都可以用它来作为排序的key。
举个字典排序的正确例子:
import operator # 注意变量名别用list,会覆盖内置类型哈 user_list = [{'name':'david','age':12},{'name':'lily','age':12},{'name':'kee','age':12},{'name':'jimi','age':12}] # 用itemgetter('name')来取字典的name键对应的值作为排序依据 sorted_users = sorted(user_list, key=operator.itemgetter('name')) print(sorted_users)
用attrgetter()的情况
- 处理自定义类的实例列表:比如你定义了一个
Person类,每个实例有name、age属性,这时候用attrgetter来按属性排序就很方便。 - 处理内置类的实例:比如
datetime对象,想按year属性排序,或者pathlib.Path对象按name属性排序。
举个类实例排序的例子:
import operator class Person: def __init__(self, name, age): self.name = name self.age = age people = [Person('david',12), Person('lily',12), Person('kee',12), Person('jimi',12)] # 用attrgetter('name')获取实例的name属性作为排序依据 sorted_people = sorted(people, key=operator.attrgetter('name')) for p in sorted_people: print(p.name)
为啥你用attrgetter()会报错?
你的列表里是字典对象,字典根本没有name这个属性——字典是用dict['name']来取值,不是dict.name。attrgetter('name')会尝试调用dict.name,自然就抛出AttributeError了。这时候换成itemgetter('name')就完全没问题啦。
额外小技巧:多键排序
不管是itemgetter还是attrgetter,都支持传入多个参数实现多维度排序。比如先按age排序,age相同再按name排序:
- 字典场景:
key=operator.itemgetter('age', 'name') - 类实例场景:
key=operator.attrgetter('age', 'name')
内容的提问来源于stack exchange,提问作者user9624737
相关产品推荐
相关产品推荐

