operator.itemgetter()以及operator.attrgetter() --来实现对公共建字典列表排序、对不原生支持比较操作的对象排序

通过公共建对字典列表排序:

1、第一种解法, 根据所有字典中共有的字段来对这些记录排序

import operator
rows = [
    {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
    {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
    {'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
    {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
]
# 通过公共建对字典序列进行排序
rows_by_fname = sorted(rows, key=operator.itemgetter('fname'))  # itengetter()方法直接接受字典的key做参数
rows_by_uid = sorted(rows, key=operator.itemgetter('uid'))
rows_by_fname
Out[3]: 
[{'fname': 'Big', 'lname': 'Jones', 'uid': 1004},
 {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
 {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
 {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}]
rows_by_uid
Out[4]: 
[{'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
 {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
 {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
 {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}]

# operator.itemgetter()函数可以接受多个键
rows_by_lfname = sorted(rows, key=operator.itemgetter('lname', 'fname')) 
rows_by_lfname
Out[6]: 
[{'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
 {'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
 {'fname': 'Big', 'lname': 'Jones', 'uid': 1004},
 {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}]

2、# 第二种解法,使用lambda表达式

rows_by_fname = sorted(rows, key=lambda r: r['fname'])  # r为rows序列中元素
rows_by_lname = sorted(rows, key=lambda r: (r['lname'], r['fname']))  # 传入元组
rows_by_fname
Out[9]: 
[{'fname': 'Big', 'lname': 'Jones', 'uid': 1004},
 {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
 {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
 {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}]
rows_by_lfname
Out[10]: 
[{'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
 {'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
 {'fname': 'Big', 'lname': 'Jones', 'uid': 1004},
 {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}]
关于对公共建字典列表排序的总结:
1、sorted()函数接受关键字参数key。这个参数代表一个可调用对象(callable),该对象从rows中接受一个单独的元素作为输入并返回一个用来做排序依据的值;

2、operator.itemgetter()函数创建的就是这样那个一个可调用对象,它接受字典的键名称、用数字表示的列表元素或是任何可以传给对象的__getitem__()方法的值;
如果传多个标记给itemgetter(), 那么它产生的可调用对象将返回一个包含所有元素在内的元组。
3、可以用lambda表达式来取代itemgetter()的功能,但是后者运行快一些。

对不原生支持比较操作的对象排序:

问题:对同一个类实例间做排序,但是它们不原生支持比较操作

class User:
    def __init__(self, user_id):
        self.user_id = user_id
    def __repr__(self):
        return 'User({})'.format(self.user_id)

users = [User(23), User(3), User(12)]
users
Out[12]: [User(23), User(3), User(12)]

# 第一种解法,lambda表达式
sorted(users, key=lambda u: u.user_id)
Out[13]: [User(3), User(12), User(23)]

# 第二种解法,operator.attrgetter()
sorted(users, key=operator.attrgetter('user_id'))  # 直接传入user_id, operator.attrgetter()函数返回一个可调用对象传给key参数
Out[14]: [User(3), User(12), User(23)]
总结:

1、operator.attrgetter()用法同 operator.itemgetter(), 也可以接受参数元组;
2、operator.attrgetter()运行效率比lambda表达式要高;
3、operator.attrgetter() 接受属性形式的参数。

你可能感兴趣的:(operator.itemgetter()以及operator.attrgetter() --来实现对公共建字典列表排序、对不原生支持比较操作的对象排序)