python中sort()、sorted()函数比较

本文探讨Python中的sort()和sorted()函数,介绍它们的作用、区别以及使用场景,包括排序方式、key参数、Operator模块函数的运用,并讨论了排序的稳定性和复杂排序策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

遇到一道题,说是列表L=[1,6,5,3,9,12,13,33],对L进行判断,如果L是升序排列的,那么输出’UP’;如果L是降序排序的,输出’DOWN’;如果上述两者都不是,那么输出’WRONG’。

当然这个问题也不难,但是我当时采取的方法比较繁琐,先将L神拷贝给L1,然后对L1排序,再将L和L1比较。

另外一种比较简洁的方法一句话就能完成,利用了sorted()函数,如下:

print ‘UP’ if L==sorted(L) else ‘DOWN’ if L==sorted(L)[::-1] else ‘WRONG’

是不是很简洁、一目了然?所以熟悉python中众多的小函数,可以帮助我们快速编程并且很简洁。

1).sorted(L)函数和L.sort()函数

sorted(iterable[,cmp,[,key[,reverse=True]]])

作用:第一个参数是一个iterable,返回值是一个对iterable中元素进行排序后的列表(list)。

可选的参数有三个,cmp、key和reverse。

>>> L=[1,6,5,3,9,12,13,33]

>>> sorted(L)
    [1, 3, 5, 6, 9, 12, 13, 33]
    >>> L
    [1, 6, 5, 3, 9, 12, 13, 33]
    可见sorted()函数并不改变原来L的顺序,只是返回一个新的列表,这个列表是按照升序排列的。

sort()函数就不一样了,它会改变原来L的顺序。

>>> L.sort()

>>> L
    [1, 6, 5, 3, 9, 12, 13, 33]

通常这个方法不如sorted(L)方便,但是List.sort()这个方法的效率要高一点。

另一个区别在于list.sort()方法只为list定义。而sorted()函数可以接收任何的iterable。

2).函数新特性(key-function模式)

从Python2.4开始,list.sort()和sorted()方法都添加了一个key参数来说明一个函数,这个函数在做比较之前会对list中的每个元素进行调用。

例如,这里是一个大小写不敏感的字符串比较:

>>> 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)
    [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

>>> sorted(student_tuples, key=lambda student: student[2])  

# sort by age [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

同样的技术适用于有named属性的对象。例如:

>>> 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 Module Functions (Operator模块中的函数)

上面的key-function模式很常见,因此Python提供了方便的函数使得祖先函数更简单和快捷。operator module有itemgetter,attrgetter,以及从Python2.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模块支持多级排序。例如先按成绩排序,再按年龄排序:

>>> 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参数。它是用于降序排序的标志。

例如,为了获得学生年龄的降序排序:

>>> 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).排序稳定性和复杂的排序

从Python2.2开始,排序都保证是稳定的。意思是当多个记录有相同的关键字时,它们原始的排序保留。

>>> 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)之前。 

这个好的特性能让你建立复杂的排序。

例如,将学生记录按成绩降序排序、按年两升序排列。先按年龄排序,再按成绩排序。

>>> s=sorted(student_object,key=attrgettter('age'))

# sort on secondary key

>>> sorted(s,key=attrgetter('grade'),reverse=True)

[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

 

附上一张秦时明月里面的图:

451f98dda144ad34c6505e47d0a20cf433ad85c4

 

Python 中,`list.sort()` 方法与 `sorted()` 函数是两种常用的排序方式,它们都可以对列表进行排序,但在使用方式和功能上存在一些关键区别。 ### `list.sort()` 方法 - `list.sort()` 是列表对象的一个方法,它会就地修改原始列表,使其按照升序排列。此方法没有返回值(即返回 `None`)[^2]。 - 由于该方法直接修改原始列表,因此适用于不需要保留原列表的情况。 - 示例代码如下: ```python list_a = [1, 2, 8, 3, 7, 9, 5, 7] list_a.sort() print("list_a after sorting:", list_a) # 输出排序后的列表 ``` ### `sorted()` 函数 - `sorted()` 是一个内置函数,可以接受任何可迭代对象(如列表、元组等),并返回一个新的已排序列表。原始数据不会被修改[^1]。 - 该函数适合需要保留原始数据,并获取排序后结果的场景。 - 示例代码如下: ```python list_a = [1, 2, 8, 3, 7, 9, 5, 7] list_b = sorted(list_a) print("Original list_a:", list_a) # 原始列表未被修改 print("Sorted list_b:", list_b) # 新列表包含排序后的值 ``` ### 参数支持 两者都支持 `key` 和 `reverse` 参数用于自定义排序规则: - `key`:指定一个函数,该函数将作用于每个元素上,再根据函数结果进行排序。 - `reverse`:布尔值,若为 `True`,则按降序排列,默认为 `False`(升序)。 示例:按字符串长度排序 ```python words = ["apple", "banana", "cherry", "date"] words.sort(key=len) print("Sorted by length:", words) words_sorted = sorted(words, key=len, reverse=True) print("Sorted by length descending:", words_sorted) ``` ### 总结 - 若需在不创建新对象的情况下修改原列表,使用 `list.sort()`。 - 若希望保持原列表不变并获得新的排序结果,则使用 `sorted()`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值