排序函数 sort()、sorted()、argsort()函数

sort()函数

python的内建排序函数有 sort、sorted两个。而sort ()可以直接对列表进行排序
用法:list.sort(func=None, key=None, reverse=False(or True))

  • 参数fun是表明此sort函数是基于何种算法进行排序的,一般默认情况下python中用的是归并排序,并且一般情况下我们是不会重写此参数的,所以基本可以忽略;
  • 参数key用来指定一个函数,此函数在每次元素比较时被调用,此函数代表排序的规则,也就是你按照什么规则对你的序列进行排序;对于复杂的对象,使用对象的下标作为key。
  • 对于reverse这个bool类型参数,当reverse=False时:为正向排序;当reverse=True时:为方向排序。默认为False。
  • 执行完后会改变原来的list,如果你不需要原来的list,这种效率稍微高点
  • 为了避免混乱,其会返回none
    例1:
>>> list = [2,8,4,6,9,1,3]
>>> list.sort()
>>> list
[1, 2, 3, 4, 6, 8, 9]#返回排序完的列表

例2:使用对象的下标作为key

from operator import attrgetter,itemgetter

list1 = [(2,'huan',23),(12,'the',14),(23,'liu',90)]

#使用默认参数进行排序,即按照元组中第一个元素进行排序
list1.sort()
print(list1)
#输出结果为[(2, 'huan', 23), (12, 'the', 14), (23, 'liu', 90)]

#使用匿名表达式重写key所代表的函数,按照元组的第二个元素进行排序
list1.sort(key=lambda x:(x[1]))
print(list1)
#[(2, 'huan', 23), (23, 'liu', 90), (12, 'the', 14)]

#使用匿名表达式重写key所代表的函数,按照元组的第三个元素进行排序
list1.sort(key=lambda x:(x[2]))
print(list1)
#[(12, 'the', 14), (2, 'huan', 23), (23, 'liu', 90)]

#使用匿名函数重写key所代表的函数,先按照元组中下标为2的进行排序,
# 对于下标2处元素相同的,则按下标为0处的元素进行排序
list1.sort(key=lambda x:(x[2],x[0]))
print(list1)
#[(12, 'the', 14), (2, 'huan', 23), (23, 'liu', 90)]

#使用operator模块中的itemgetter函数进行重写key所代表的函数,按照下标为1处的元素进行排序
list1.sort(key=itemgetter(1))
print(list1)
#[(2, 'huan', 23), (23, 'liu', 90), (12, 'the', 14)]

#使用operator模块中的itemgetter函数进行重写key所代表的函数,按照下标为2处的元素进行排序
#operator.itemgetter()   ----- 通过下标
list1.sort(key=itemgetter(2))
print(list1)
# [(12, 'the', 14), (2, 'huan', 23), (23, 'liu', 90)]

# 此处可以类比lambda中的排序方法,就不再解释
list1.sort(key=itemgetter(2,0))
print(list1)
#[(12, 'the', 14), (2, 'huan', 23), (23, 'liu', 90)]

sorted() 函数

sorted与sort的区别在于:
sort()可以对列表中的元素进行排序,而全局性的sorted()函数则对所有可迭代的序列都是适用的;并且sort()函数是内置函数,会改变当前对象,而sorted()函数只会返回一个排序后的当前对象的副本,而不会改变当前对象。
用法:sorted(iterable,cmp,key,reverse)

  • 该函数也含有reverse这个bool类型的参数,当reverse=False时:为正向排序(从小到大);当reverse=True时:为反向排序(从大到小)。当然默认为False
  • 执行完后会有返回一个新排序好的list

例1:

>>> list = [2,8,4,1,5,7,3]
>>> other = sorted(list)
>>> other
[1, 2, 3, 4, 5, 7, 8]

例2:使用cmp函数排序,cmp是带两个参数的比较函数

list1 = [('david', 90), ('mary',90), ('sara',80),('lily',95)]

print(sorted(list1,cmp = lambda x,y: cmp(x[0],y[0])))#按照第一个位置的字母序排序
#[('david', 90), ('lily', 95), ('mary', 90), ('sara', 80)]

print(sorted(list1,cmp = lambda x,y: cmp(x[1],y[1])))#按照第二个位置的数字序排序

#[('sara', 80), ('david', 90), ('mary', 90), ('lily', 95)]

例3:区分大小写的字符串比较排序

>>> sorted("This is a test string from Andrew".split(), key=str.lower)
['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

例4:使用对象的属性进行操作

>>> class Student:
...     def __init__(self, name, grade, age):
...         self.name = name
...         self.grade = grade
...         self.age = age
...     def __repr__(self):
...         return repr((self.name, self.grade, self.age))
>>>
>>> student_objects = [
...     Student('john', 'A', 15),
...     Student('jane', 'B', 12),
...     Student('dave', 'B', 10),
... ]
>>> sorted(student_objects, key=lambda student: student.age)   # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

Operator Module Functions
这个操作模块有:

  • operator.itemgetter() —– 通过下标

  • operator.attrgetter() —– 通过参数

  • operator.methodcaller() —–这个函数是对某个对象的使用固定参数进行排序,例如:str.count()函数可以计算每个字符串对象中含有某个参数的个数,那运用这个函数我就可以通过 str.count() 计算出某个字符的个数从而来确定排序的优先级。详见例6

使用这几个函数,对于上面 Key Function 的例子处理起来将会更加的简便和快速
先一块介绍 operator.itemgetter()operator.attrgetter() 这俩个,会更加容易理解:
例5:

>>> from operator import itemgetter
>>> sorted(student_tuples, key=itemgetter(1,2))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]

>>> sorted(student_objects, key=attrgetter('grade', 'age'))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]

>>> list = [('d',3),('a',5),('d',1),('c',2),('d',2)]
>>> sorted(list, key=itemgetter(0,1))
[('a', 5), ('c', 2), ('d', 1), ('d', 2), ('d', 3)]

例6:

>>> from operator import methodcaller
>>> messages = ['critical!!!', 'hurry!', 'standby', 'immediate!!']
>>> sorted(messages, key=methodcaller('count', '!'))
['standby', 'hurry!', 'immediate!!', 'critical!!!']

注意事项
例7:排序的稳定性。从python2.2版本开始,排序是保障稳定性的,意思就是说,当复杂的排序中,对象有相同的key的时候,会保持原有的顺序不变

>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> sorted(data, key=itemgetter(0))
[('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]
#('blue',1) 和 (‘blue’,2) 的顺序还是维持原来那样不改变。

例8:复杂排序


#这个排序的属性可以让你在一系列的步骤中构建复杂的排序操作。
#例如上面的例子,排序中,我想先通过 “成绩grand” 进行降序操作,
#然后再通过“年龄age” 进行升序操作,首先先通过 “年龄age” 排序,
#然后再通过 “成绩grand” 排序
>>> s = sorted(student_objects, key=attrgetter('age'))     # sort on secondary key
>>> sorted(s, key=attrgetter('grade'), reverse=True)       # now sort on primary key, descending
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

argsort() 函数

numpy中的函数,返回对数组进行排序的索引(ndarray, int)。使用由kind给定的关键字指定的算法沿给定轴执行间接排序。它返回一个索引数组,其形状与沿着给定轴数组形状相同。
用法为: numpy.argsort(a, axis=-1, kind='quicksort', order=None)
例1:返回的是数组值从小到大的索引值

One dimensional array:一维数组

>>> x = np.array([3, 1, 2])
>>> np.argsort(x)
array([1, 2, 0])

Two-dimensional array:二维数组

>>> x = np.array([[0, 3], [2, 2]])
>>> x
array([[0, 3],
[2, 2]])

>>> np.argsort(x, axis=0) #按列排序
array([[0, 1],
[1, 0]])

>>> np.argsort(x, axis=1) #按行排序
array([[0, 1],
[0, 1]])

例2:按降序排列

>>> x = np.array([3, 1, 2])
>>> np.argsort(x) #按升序排列
array([1, 2, 0])
>>> np.argsort(-x) #按降序排列
array([0, 2, 1])

例3:另外一种按降序排列的方法

>>> a = x[np.argsort(x)]
>>> a
array([1, 2, 3])
>>> a[::-1]
array([3, 2, 1]) 
>>> a = x.argsort().[::-1]

例4:得到通过索引值排序后的数组

>>> x = np.array([3, 1, 2])
>>>> x[np.argsort(x)] #通过索引值排序后的数组
array([1, 2, 3])
>>> x[np.argsort(-x)]
array([3, 2, 1])

参考文献:

https://www.cnblogs.com/yushuo1990/p/5880041.html
https://www.cnblogs.com/ShaunChen/p/6205330.html
https://www.cnblogs.com/jonm/p/8281228.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值