operator 中itemgetter、attrgetter

你有一个字典列表,你想根据某个或某几个字典字段来排序这个列表。通过使用 operator 模块的 itemgetter 函数,可以非常容易的排序这样的数据结构。假设你从数据库中检索出来网站会员信息列表,并且以下列的数据结构返回:

from operator import itemgetter, attrgetter

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=itemgetter('fname'))
rows_by_uid = sorted(rows, key=itemgetter('uid'))
print(rows_by_fname)
print(rows_by_uid)

# itemgetter() 函数也支持多个 keys,比如下面的代码
rows_by_lfname = sorted(rows, key=itemgetter('lname', 'fname'))
print(rows_by_lfname)

# 在上面例子中, rows 被传递给接受一个关键字参数的 sorted() 内置函数。这个
# 参数是 callable 类型,并且从 rows 中接受一个单一元素,然后返回被用来排序的值。
# itemgetter() 函数就是负责创建这个 callable 对象的。

# operator.itemgetter() 函数有一个被 rows 中的记录用来查找值的索引参数。可
# 以是一个字典键名称,一个整形值或者任何能够传入一个对象的 __getitem ()__ 方法的
# 值。 如果你传入多个索引参数给 itemgetter() ,它生成的 callable 对象会返回一个
# 包含所有元素值的元组,并且 sorted() 函数会根据这个元组中元素顺序去排序。但你
# 想要同时在几个字段上面进行排序 (比如通过姓和名来排序,也就是例子中的那样) 的
# 时候这种方法是很有用的。

# itemgetter() 有时候也可以用 lambda 表达式代替,比如:

rows_by_fname = sorted(rows, key=lambda r: r['fname'])
rows_by_lfname = sorted(rows, key=lambda r: (r['lname'], r['fname']))
print(rows_by_fname)
print(rows_by_lfname)

# 这种方案也不错。但是,使用 itemgetter() 方式会运行的稍微快点。因此,如果
# 你对性能要求比较高的话就使用 itemgetter() 方式。

# 最后,不要忘了这节中展示的技术也同样适用于 min() 和 max() 等函数。比如:
print(min(rows, key=itemgetter('uid')))
print(max(rows, key=itemgetter('uid')))

# 你想排序类型相同的对象,但是他们不支持原生的比较操作。

# 内置的 sorted() 函数有一个关键字参数 key , 可以传入一个 callable 对象给它,
# 这个 callable 对象对每个传入的对象返回一个值,这个值会被 sorted 用来排序这些
# 对象。比如,如果你在应用程序里面有一个 User 实例序列,并且你希望通过他们的
# user id 属性进行排序,你可以提供一个以 User 实例作为输入并输出对应 user id 值
# 的 callable 对象。比如:


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(99)]
print(users)
print(sorted(users, key=lambda u: u.user_id))
print(sorted(users, key=attrgetter('user_id')))

# 选 择使 用 lambda 函数 或者 是 attrgetter() 可能 取 决于 个人 喜好。 但是,
# attrgetter() 函数通常会运行的快点,并且还能同时允许多个字段进行比较。这
# 个跟 operator.itemgetter() 函数作用于字典类型很类似 (参考 1.13 小节)。例如,如
# 果 User 实例还有一个 first name 和 last name 属性,那么可以向下面这样排序:

print(min(users, key=attrgetter('user_id')))
print(max(users, key=attrgetter('user_id')))



猜你喜欢

转载自blog.csdn.net/MZP_man/article/details/114080812
今日推荐