我有以下代码:
# 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
?
Python到底是如何对表进行排序的?我可以逆向排序吗?
如何根据两列(例如第一个年龄,然后如果年龄与 b 名称相同)对它进行排序?
没有
operator
我怎么能做到呢?
看起来你对这些东西有点困惑。
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 中,函数是一等公民,因此您可以将它们作为参数传递给其他函数。
其他问题:
reverse=True
:a.sort(key=..., reverse=True)
itemgetter
与多个索引一起使用:operator.itemgetter(1,2)
,或与 lambda 一起使用:lambda elem: (elem[1], elem[2])
。这样,迭代器是为列表中的每个项目动态构造的,然后按字典顺序(?)相互比较(比较第一个元素,如果相等 - 比较第二个元素,等等)a[2,1]
获取 [3,2] 处的值(索引从零开始)。使用运算符...这是可能的,但不像索引那么干净。详情请参阅文档:
简单来说:
key=
的sort
参数需要一个键函数(应用于要排序的对象)而不是单个键值和operator.itemgetter(1)
将为您提供的:一个从类似列表的对象中获取第一项的 function。 (更准确地说,这些是 callables,而不是函数,但这是一个经常可以忽略的区别。)
你问了很多问题,你可以通过阅读文档来回答自己,所以我会给你一个一般性建议:阅读它并在 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))
请参阅排序方法。
#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
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']]
>>>
使用用户定义函数对数组进行排序的最简单方法是使用 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)))
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)
两个打印语句返回相同的结果
您可以使用
reverse= True
反转排序
要根据年龄和姓名排序,您可以使用
itemgetter(1,0)
。年龄位于索引位置 1,姓名位于索引位置 0
a.sort(key=operator.itemgetter(1,0))
您可以使用 Lambda 函数代替 Operator 模块中的 itemgetter 函数,但 itemgetter 比 lambda 快一点,因此当考虑执行速度和内存时,建议使用 itemgetter。
c.sort(key=lambda x: x[1],reverse= True)