operator.itemgetter() 和 sort() 如何工作?

问题描述 投票:0回答:7

我有以下代码:

# initialize
a = []

# create the table (name, age, job)
a.append(["Nick", 30, "Doctor"])
a.append(["John",  8, "Student"])
a.append(["Paul", 22, "Car Dealer"])
a.append(["Mark", 66, "Retired"])    

# sort the table by age
import operator
a.sort(key=operator.itemgetter(1))    

# print the table
print(a)

它创建一个 4x3 的表,然后按年龄对其进行排序。我的问题是,

key=operator.itemgetter(1)
到底是做什么的?
operator.itemgetter
函数是否返回项目的值?为什么我不能直接输入类似
key=a[x][1]
的内容?或者我可以吗? with 运算符如何打印像
3x2
这样的形式的某个值,即
22

  1. Python到底是如何对表进行排序的?我可以逆向排序吗?

  2. 如何根据两列(例如第一个年龄,然后如果年龄与 b 名称相同)对它进行排序?

  3. 没有

    operator
    我怎么能做到呢?

python sorting operator-keyword
7个回答
176
投票

看起来你对这些东西有点困惑。

operator
是一个内置模块,提供了一组方便的操作符。用两个词来说
operator.itemgetter(n)
构造一个可调用对象,假设一个可迭代对象(例如列表、元组、集合)作为输入,并从中取出第 n 个元素。

所以,你不能在那里使用

key=a[x][1]
,因为Python不知道
x
是什么。相反,您可以使用
lambda
函数(
elem
只是一个变量名,没有魔法):

a.sort(key=lambda elem: elem[1])

或者只是一个普通的函数:

def get_second_elem(iterable):
    return iterable[1]

a.sort(key=get_second_elem)

因此,这里有一个重要的注意事项:在 python 中,函数是一等公民,因此您可以将它们作为参数传递给其他函数。

其他问题:

  1. 是的,可以反向排序,只需添加
    reverse=True
    a.sort(key=..., reverse=True)
  2. 要按多列排序,您可以将
    itemgetter
    与多个索引一起使用:
    operator.itemgetter(1,2)
    ,或与 lambda 一起使用:
    lambda elem: (elem[1], elem[2])
    。这样,迭代器是为列表中的每个项目动态构造的,然后按字典顺序(?)相互比较(比较第一个元素,如果相等 - 比较第二个元素,等等)
  3. 您可以使用
    a[2,1]
    获取 [3,2] 处的值(索引从零开始)。使用运算符...这是可能的,但不像索引那么干净。

详情请参阅文档:

  1. operator.itemgetter
    解释了
  2. Python 中按自定义键对列表进行排序

55
投票

Python初学者的答案

简单来说:

  1. key=
    sort
    参数需要一个键函数(应用于要排序的对象)而不是单个键
  2. 这正是
    operator.itemgetter(1)
    将为您提供的:一个从类似列表的对象中获取第一项的 function

(更准确地说,这些是 callables,而不是函数,但这是一个经常可以忽略的区别。)


22
投票

你问了很多问题,你可以通过阅读文档来回答自己,所以我会给你一个一般性建议:阅读它并在 python shell 中进行实验。你会看到

itemgetter
返回一个可调用的:

>>> func = operator.itemgetter(1)
>>> func(a)
['Paul', 22, 'Car Dealer']
>>> func(a[0])
8

要以不同的方式执行此操作,您可以使用

lambda
:

a.sort(key=lambda x: x[1])

并反转它:

a.sort(key=operator.itemgetter(1), reverse=True)

按多列排序:

a.sort(key=operator.itemgetter(1,2))

请参阅排序方法


1
投票
#sorting first by age then profession,you can change it in function "fun".
a = []

def fun(v):
    return (v[1],v[2])

# create the table (name, age, job)
a.append(["Nick", 30, "Doctor"])
a.append(["John",  8, "Student"])
a.append(["Paul",  8,"Car Dealer"])
a.append(["Mark", 66, "Retired"])

a.sort(key=fun)


print a

0
投票
a = []
a.append(["Nick", 30, "Doctor"])
a.append(["John",  8, "Student"])
a.append(["Paul",  8,"Car Dealer"])
a.append(["Mark", 66, "Retired"])
print a

[['Nick', 30, 'Doctor'], ['John', 8, 'Student'], ['Paul', 8, 'Car Dealer'], ['Mark', 66, 'Retired']]

def _cmp(a,b):     

    if a[1]<b[1]:
        return -1
    elif a[1]>b[1]:
        return 1
    else:
        return 0

sorted(a,cmp=_cmp)

[['John', 8, 'Student'], ['Paul', 8, 'Car Dealer'], ['Nick', 30, 'Doctor'], ['Mark', 66, 'Retired']]

def _key(list_ele):

    return list_ele[1]

sorted(a,key=_key)

[['John', 8, 'Student'], ['Paul', 8, 'Car Dealer'], ['Nick', 30, 'Doctor'], ['Mark', 66, 'Retired']]
>>> 

0
投票

使用用户定义函数对数组进行排序的最简单方法是使用 Functools 中的 cmp_to_key。 这是示例代码:

from functools import cmp_to_key

def mine(x,y):
    if(x[1]!=y[1]): return x[1]>y[1]
    else: return x[0]>y[0]
    
a = []
a.append(["Nick", 30, "Doctor"])
a.append(["John",  8, "Student"])
a.append(["Paul", 22, "Car Dealer"])
a.append(["Mark", 66, "Retired"])  

def mine(a,b):
    if a[1] > b[1]:
        return 1
    elif a[1] < b[1]:
        return -1
    else:
        if a[0] > b[0]:
            return 1
        else:
            return 0
                     
print(sorted(a,key = cmp_to_key(mine)))

0
投票

Python 的

itemgetter
函数是一个强大的工具,可以轻松访问和操作列表、元组和字典中的项目。它可以采用多个参数,允许您指定要检索项目的顺序。

b = a
c = a

a.sort(key=operator.itemgetter(1), reverse= True)    
print(a)

b = sorted(b, key=operator.itemgetter(1), reverse=True)
print(b)

两个打印语句返回相同的结果

  1. 您可以使用

    reverse= True

    反转排序
  2. 要根据年龄和姓名排序,您可以使用

    itemgetter(1,0)
    。年龄位于索引位置 1,姓名位于索引位置 0

    a.sort(key=operator.itemgetter(1,0))

  3. 您可以使用 Lambda 函数代替 Operator 模块中的 itemgetter 函数,但 itemgetter 比 lambda 快一点,因此当考虑执行速度和内存时,建议使用 itemgetter。

    c.sort(key=lambda x: x[1],reverse= True)

© www.soinside.com 2019 - 2024. All rights reserved.