孽之极 发表于 2023-7-1 16:24:37

python的sort函数与sorted函数排序

1. sort函数
  sort函数为python内置的列表排序高阶函数,所谓高阶函数,也就是参数为函数或返回值为函数。
  先看个简单的例子:
# 数字列表的排序示例<br>nums =
nums.sort()<br>print(nums)# 输出:  可以发现排序后,改变了原列表的顺序。而且sort()函数没有返回值,或者说返回值是None。再看sort函数的语法:
  sort函数的语法是:list.sort(key=None, reverse=False)。
  参数说明:
  key:指定用于排序的函数,可以指定一个函数,这个函数接受一个参数并返回一个用于排序的关键字,默认为None,表示按照列表的元素排序,但是要求每个元素的数据类型相同。
  reverse:如果为True,则列表会以降序排序,默认为False,即升序排序。
nums =
nums.sort(reverse=True)
print(nums)# 输出:
#如果是字符,元素就应该统一全部是字符,按照编码大小比较。
nums = ['5', '2', '9','T' '1', '7','!','t','1']
nums.sort(reverse=True)
print(nums)# 输出:['t', 'T1', '9', '7', '5', '2', '1', '!']  如果每个元素为列表或元组、字典,在key=None的情况下又该如何比较大小呢?
当key=None时:

[*]元素为列表的列表排序
  讲解元素为列表的列表之前先看个代码:
list01=
list02=
print(list01>list02)#True  可以看到是先比较两个列表元素的第一个,显然3>0,运算结果是True(如果相等,继续比较后面的,注意,并不是比较列表的长度大小)。
  再看下面例子:
# 比较时,相互比较的元素数据类型要相同,否则报错
list01=
list02=['0',1,1]
print(list01>list02)#报错报错报错TypeError: '>' not supported between instances of 'int' and 'str'  还有一种特殊的例子:
list01=
list02=
print(list01>list02)#True  这种情况不会报错,因为比较第一个元素时,已经能分出大小了。
  元素为列表的排序先看2个例子,再分析。
lst1=[,]
lst2=[,]
print(lst1>lst2)#False

lst1=[,]
lst2=[,]
print(lst1>lst2)#False  所以,当元素为列表时,依然按照前面的方法比较大小,lst中的第一个元素和lst中的第一个元素比较大小,与比较大小再次按照列表的比较大小规则即可。下面为key=None时,调用sort后的排序例子。
mylist = [, , , , , , , ]
mylist.sort()
print(mylist)#[, , , , , , , ]  通过上面例子可以发现,当key=None时,排序规则和列表的简单排序一样,比如>,前面两个元素相等时,就看长度,长度大的大。

[*]元素为元组的列表
  先说元组,由于sort是对原址排序,而元组内部不可修改,所以直接对元组是不能排序的。但是,我们的数据类型是列表,列表的每一个元素是元组,由于整体是列表类型,当然可以调用sort函数排序了。先看元组如何比较大小:
print((4,2)>(2,3))#True
print((4,2)>(2,2,1))#True  也就是说元组比较大小和简单列表比较大小的规则相同。
tuple1=[(4,2),(2,3),(3,1)]
tuple1.sort()
print(tuple1)#[(2, 3), (3, 1), (4, 2)]

[*]元素为字典的列表
  先看个例子:
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 2, 'a': 1}
dict3 = {'a': 1, 'b': 3}
print(dict1 == dict2)# True,与顺序无关
print(dict1 == dict3)# False
print(dict1 > dict3)# 报错TypeError: '>' not supported between instances of 'dict' and 'dict'  两个字典不能直接比较大小,==(调用了__eq__()函数)是比较内容是不是一样的。所以元素为字典的列表是不能直接调用sort函数排序的。
当key不为None:
  按照自定义的规则进行排序。我们需要给key传入一个函数作为参数,按照函数的规则进行排序。这个函数接受一个参数并返回一个用于排序的关键字。具体是什么意思呢?先看个简单的例子:
lst=[, , , , ]
def sort_by_first_element(lst):
    return lst
lst.sort(key=sort_by_first_element)
print(lst)#[, , , , ]  将参数传入给了sort函数的key,观察排序的结果,可以发现上面代码元素的排序是按照每个元素(仍然是列表)的第一个元素进行比较大小的,不比较第二个元素,若第一个元素相等,则两个元素相等,不改变顺序,比如与按照排序规则是相等的。进一步,观察sort_by_first_element这个函数,返回值是lst。似乎返回的是。又是怎么做到比较每一个元素(列表)的第一个元素的呢?仔细思考,sort_by_first_element(lst):中的lst其实是形参,另外,可以发现一定是sort函数内部实现了排序,其根据给定原始列表信息lst及函数sort_by_first_element返回值是能实现排序结果的,也就是说想要返回元素的第一个元素,那么sort_by_first_element(lst)中的lst可能传入参数时像这样:sort_by_first_element(lst),sort_by_first_element(lst)等,再返回lst时,就真正做到了返回元素的第一个元素。这里用自己的方法实现一下sort函数(猜测python内部可能采用了快速排序用C语言实现了sort函数,实现排序)。代码如下:
"""
MyLIst类定义了sort方法用于对列表排序
"""
class MyList:
    def __init__(self, mylist=None):
      """
      :param mylist: 传入一个列表
      """
      self.mylist = mylist

    def sort(self, key=None):# key传入函数名
      print("对象调用了MyList类里面的sort方法")
      lst = []
      for item in self.mylist:
            lst.append(item)
      print("排序前:", lst)
      # 冒泡排序
      try:
            for i in range(len(self.mylist) - 1):# [0,长度-1),只需要循环长度-1 次就能排序完,最后一个元素可以不用排序
                for j in range(0, len(self.mylist) - 1 - i):
                  if key(self.mylist) > key(self.mylist):
                        self.mylist, self.mylist = self.mylist, self.mylist# python的语法支持这种交换
      except Exception as e:
            print(e)
            print("可能是索引越界了")<br>
    def __str__(self):
      return str(self.mylist)

def sort_by_first_element(lst):
    return lst

def sort_by_second_element(lst):
    return lst

if __name__ == '__main__':
    mylist=MyList([, ,, , ])
    mylist.sort(key=sort_by_first_element)#对第一个元素进行排序
    print("排序后" ':',end=' ')
    print(mylist)#调用__str__()

    mylist2 = MyList([, , , , ])
    #或者传入lambda匿名函数
    mylist2.sort(key=lambda e:e)#对第二个元素进行排序,相当于 mylist.sort(key=sort_by_second_element)
    print("排序后" ':', end=' ')
    print(mylist2)  运行结果:

  key后面传入lambda匿名函数,更简洁。我们可以改变key传入的函数,来改变排序规则,下面给一个自定义按长度实现排序的例子:
mylist=[, ,, , ,,,]
mylist.sort(key=lambda e:len(e))#对第一个元素进行排序
print(mylist)#[, , , , , , , ]  根据字典的值对列表进行排序:
lst = [{'name': 'Alice', 'age': 25},
       {'name': 'Bob', 'age': 30},
       {'name': 'Charlie', 'age': 20}]
# 使用sort方法排序(原址排序)
lst.sort(key=lambda x: x['age'])#改变原列表顺序
print(lst)# 输出:[{'name': 'Charlie', 'age': 20}, {'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}]2. sorted函数
  sorted函数也是Python内置的一个函数,用于对可迭代对象进行排序操作。它的基本用法如下:
  sorted(iterable, key=None, reverse=False)
  参数:
  iterable:可迭代对象,比如列表、元组、字符串等。
  key:可选参数,用于指定排序的关键字函数,它接收一个参数并返回一个用于排序的关键字。如果不指定该参数,则默认按照元素的自然顺序排序。
  reverse:可选参数,为一个布尔值,默认为False,表示升序排序。如果设置为True,则表示降序排序。
  返回值:返回一个新的已排序的列表。
lst =
sorted_lst = sorted(lst)
print(sorted_lst)# 输出:,没有改变lst的元素顺序

str = "hello"
sorted_str = sorted(str)
print(sorted_str)# 输出:['e', 'h', 'l', 'l', 'o']<br>#注意并没有改变原来str字符串的序列顺序,而且字符串本身也不能改变  看一个key不为None的例子
lst = [{'name': 'Alice', 'age': 25},
       {'name': 'Bob', 'age': 30},
       {'name': 'Charlie', 'age': 20}]
# 使用sorted函数排序
sorted_lst = sorted(lst, key=lambda x: x['age'])#返回新的列表,不改变原列表顺序
print(sorted_lst)# 输出:[{'name': 'Charlie', 'age': 20}, {'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}]<br> 

小结:sort函数用于列表的排序,更改原序列。而sorted用于可迭代对象的排序(包括列表),返回新的序列;注意,如果元素逐个比较相等时,就比较长度,比如:
页: [1]
查看完整版本: python的sort函数与sorted函数排序