98

我有以下代码:

# 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]?或者我可以吗?运算符如何打印表单的某个值,例如3x2which is 22

  1. Python究竟是如何对表格进行排序的?我可以反向排序吗?

  2. 如何根据第一年龄等两列对其进行排序,然后如果年龄是相同的 b 名称?

  3. 没有我怎么办operator

4

6 回答 6

146

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

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=Truea.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 中按自定义键对列表进行排序
于 2013-09-03T15:35:42.663 回答
46

Python初学者的答案

用更简单的话来说:

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

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

于 2015-04-14T14:03:19.643 回答
19

你问了很多问题,你可以通过阅读文档来回答自己,所以我会给你一个一般性的建议:阅读它并在 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))

请参阅排序方法

于 2013-09-03T15:31:27.420 回答
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
于 2016-06-16T07:50:40.187 回答
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']]
>>> 
于 2017-03-27T16:51:40.150 回答
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)))
于 2021-12-16T07:22:32.757 回答