Python中sort()和sorted()的区别

1、sort 与 sorted 区别

① sort 是应用在 list 上的方法,属于列表的成员方法,sorted 可以对所有可迭代的对象进行排序操作。

② list 的 sort 方法返回的是对已经存在的列表进行操作,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。

③ sort使用方法为ls.sort(),而sorted使用方法为sorted(ls)。

通过代码,简单解释sort()与sorted()的区别:

2、sort()的理解使用

sort() 函数用于对原列表进行排序,如果指定参数,则使用比较函数指定的比较函数。

语法如下:

list.sort(cmp=None, key=None, reverse=False)

参数:

cmp – 可选参数,如果指定了该参数会使用该参数的方法进行排序。

key – 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。

reverse – 排序规则,reverse = True 降序, reverse = False 升序(默认)。

返回值:

该函数没有返回值,但会对数组/列表进行排序​​​​​​​

a = [1, 3, 4, 2]

# 1.一般调用
a.sort()  # 调用1,无返回值,a=[1, 2, 3, 4]
a.sort(reverse=True)  # 逆序, a=[4, 3, 2, 1]
b = sorted(a)  # 调用2,有返回值, b=[1, 2, 3, 4]


# 2.通过指定列表中的元素排序输出列表
# 获取列表的第二个元素
def takeSecond(elem):
    return elem[1]


# 列表
random = [(2, 2), (3, 4), (4, 1), (1, 3)]
# 指定第二个元素排序
random.sort(key=takeSecond)  # 按列表每个元组中第二位元素的升序排序整个数组
# 输出类别
print(random)  # [(4, 1), (2, 2), (1, 3), (3, 4)]

 

需要注意的地方:

① cmp作为sort()参数使用(python2中使用,python3已弃用)

② python3中也取消了函数传入机制,可以构造排序函数递给key实现。

示例:

>>> cmp(42,32)
1
>>> cmp(99,100)
-1
>>> cmp(10,10)
0
>>> numbers = [5,2,9,7]
>>> numbers.sort()
>>> numbers.sort(cmp) # 通过调用cmp(x,y)来排序,与不传入cmp参数时效果一样(结果相同,但实际执行流程不同)
>>> numbers
[2,5,7,9]

 

或者自定义函数传入:

numbers = [5, 2, 9, 7]
def reverse_numbers(x, y):
	return y - x

numbers.sort(cmp = reverse_numbers) # 逆序,numbers=[9,7,5,2]

# 上述用lambda匿名函数也可以写成:
numbers.sort(lambda x, y: y-x) # numbers=[9,7,5,2]

算法中的应用:

例:把数组排成最小的数

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

class Solution:
    def PrintMinNumber(self, numbers):
        # write code here
        if not len(numbers):
            return ""
        arr = [str(x) for x in numbers]
        arr.sort(lambda x,y:cmp(x+y,y+x)) # 让x和y及y和x拼接后的字符串进行大小比较,若x+y<y+x,则x,y的前后位置不变;反之x,y交换位置(y提到x之前)。
        return int("".join(arr))

3、sorted()的理解使用

sorted() 函数对所有可迭代的对象进行排序操作

语法如下:

sorted(iterable, cmp=None, key=None, reverse=False)

参数说明:

iterable – 可迭代对象。

cmp – 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。(一般省略)

key – 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。

常用的用来作为参数key的函数有 lambda函数和operator.itemgetter()
尤其是列表元素为多维数据时,需要key来选取按哪一位数据来进行排序

reverse – 排序规则,reverse = True 降序 , reverse = False 升序(默认)。

返回值

返回重新排序的列表;

需要注意:列表的元素可以是多样的,返回列表的形式与输入列表的形式一致。

元组和集合同样可以使用sorted()函数!

值得注意的是:
即使输入的是一个集合和元组,输出结果仍然是一个列表,因为sorted()函数根据定义会返回一个新列表,如果返回的对象需要匹配输入类型,则可以将其转化为新类型。
如果试图将结果列表转换回集合类型,请注意,按照定义而言,集合是无序的。

1)一般用法

当元素为一维数字或字母时,结果返回一个新的列表,其中元素按升序或降序排列(根据reverse参数来决定)。

list = [1, 5, 7, 2, 4]
print(sorted(list))

输出:
[1, 2, 4, 5, 7]

list = ['d', 'c', 'f', 'a', 'z']
print(sorted(list))

输出:
['a', 'c', 'd', 'f', 'z']

list = ['vz', '1bf', 'gc', 'ak', '2qz']#若为字符串,则跟据第一位的数字-字母顺序来排列
print(sorted(list))

输出:
['1bf', '2qz', 'ak', 'gc', 'vz']

2)各类使用举例

例1:正序排序

a = [20, 5, 6, 7, 8, 1]
res1 = sorted(a)  # 正序排序
print(res1)

输出: [1, 5, 6, 7, 8, 20]

例2:逆序排序

a = [20, 5, 6, 7, 8, 1]
res1 = sorted(a, reverse=True)  # 逆序排序
print(res1)

输出: [20, 8, 7, 6, 5, 1]

例3:根据字符长短进行排序

lst = ['ccc', 'aaaaaa', 'ff', 'd']

def func(n):
    return len(n)

print(sorted(lst, key=func))

输出:[‘d’, ‘ff’, ‘ccc’, ‘aaaaaa’]

例4:和lambda()函数配合使用

lst = ['ccc', 'aaaaaa', 'ff', 'd']

# 根据字符长短进行排序
print(sorted(lst, key=lambda n: len(n)))

输出:[‘d’, ‘ff’, ‘ccc’, ‘aaaaaa’]

例5:对列表中的元素进行排序,key比较

list1 = [('david', 90), ('mary', 90), ('sara', 80), ('lily', 95)]
L1 = sorted(list1, key=lambda x: x[0])
L2 = sorted(list1, key=lambda x: x[1])
print(L1)
print(L2)

输出:
[('david', 90), ('lily', 95), ('mary', 90), ('sara', 80)]
[('sara', 80), ('david', 90), ('mary', 90), ('lily', 95)]

例6:sorted() 用于字典dictionary

字典排序

① 返回的是排序后的key

dict = {1: 'A', 3: 'C', 2: 'B'}
res1 = sorted(dict)
print(res1)

输出: [1, 2, 3]

② 对字典进行排序,需将字典通过items()转换为元组列表

di={'zhang':4,'pan':7,'wang':4,'li':2,'hu':2}
di.items()

输出:
dict_items([(‘zhang’, 4), (‘pan’, 7), (‘wang’, 4), (‘li’, 2), (‘hu’, 2)])

③ sorted()函数默认对字典的key值进行排序

sorted(di.items())

输出:[(‘hu’, 2), (‘li’, 2), (‘pan’, 7), (‘wang’, 4), (‘zhang’, 4)]

sorted(di.items(),reverse=True)

输出:[(‘zhang’, 4), (‘wang’, 4), (‘pan’, 7), (‘li’, 2), (‘hu’, 2)]

④ 如果想要对字典的value值进行排序,可以设置key参数

sorted(di.items(),reverse=True,key=lambda x:x[1])

输出:[(‘pan’, 7), (‘zhang’, 4), (‘wang’, 4), (‘li’, 2), (‘hu’, 2)]

⑤ 嵌套排序

先对字典的value值进行降序排序,value值相同,对相同value值的key值进行降序排序。

sorted(sorted(di.items(),reverse=True,key=lambda x:x[0]),reverse=True,key=lambda item:item[1])

输出:[(‘pan’, 7), (‘zhang’, 4), (‘wang’, 4), (‘li’, 2), (‘hu’, 2)]

3)sorted()函数四种重要的特性

1)sorted()函数不需要定义,它是一个内置函数,可以在标准的Python安装中使用。

2)在没有额外的参数的情况下,sorted()函数按照升序对值进行排列,也就是按照从小到大的顺序。

3)原始的numbers不会改变,因为sorted()函数提供了一个新的有序的输出结果,并且不改变原始值的顺序。

4)当sorted()函数被调用时,它会提供一个有序的列表作为返回值。

最后一点意味着列表可以使用sorted()函数,并且输出结果可以立刻赋值给一个变量。

4、sort()和sorted()高级排序技巧(key的使用)

1)排序基础

简单的升序排序只需要调用sorted()方法,它返回一个新的list,新的list的元素基于小于运算符(lt)来排序。

>>> sorted([5, 2, 3, 1, 4])
[1, 2, 3, 4, 5]

也可以使用list.sort()方法来排序,此时list本身将被修改,通常这种方法不如sorted()方便,但如果你不需要保留原来的list,这种方法更有效。

>>> a = [5, 2, 3, 1, 4]
>>> a.sort()
>>> a
[1, 2, 3, 4, 5]

另一个不同就是list.sort()方法仅被定义在list中,相反地sorted()方法对所有的可迭代序列都有效。

>>> sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'})
[1, 2, 3, 4, 5]

2)key参数/函数

例如通过key指定的函数来忽略字符串的大小写:

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

key参数的值为一个函数,此函数只有一个参数且返回一个值用来进行比较。

更广泛的使用情况是用复杂对象的某些值来对复杂对象的序列排序,例如

>>> student_tuples = [
        ('john', 'A', 15),
        ('jane', 'B', 12),
        ('dave', 'B', 10),
]
>>> sorted(student_tuples, key=lambda student: student[2])   # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

同样的技术对拥有命名属性的复杂对象也适用

>>> 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)]

3)Operator 模块函数

operator模块有itemgetter,attrgetter,从2.6开始还增加了methodcaller方法。

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


operator模块还允许多级的排序,例如,先以grade,然后再以age来排序:
代码如下:
```python
>>> 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)]

4)升序和降序

list.sort()和sorted()都接受一个参数reverse(True or False)来表示升序或降序排序。

例如对上面的student降序排序

>>> sorted(student_tuples, key=itemgetter(2), reverse=True)
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
>>> sorted(student_objects, key=attrgetter('age'), reverse=True)
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]

5)排序的稳定性和复杂排序

多个元素如果有相同的key,则排序前后他们的先后顺序不变。

>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> sorted(data, key=itemgetter(0))
[('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]

注意在排序后’blue’的顺序被保持了,即’blue’, 1在’blue’, 2的前面。

更复杂的你可以构建多个步骤来进行更复杂的排序,例如对student数据先以grade降序排列,然后再以age升序排列。

>>> 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)]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值