说起怎么排序Python,这事儿嘛,用Python时间久了,谁还没遇上几次要给东西排队的情况?列表、字典、自定义对象,大大小小,总得有个先来后到。别以为这简简单单一个“排序”,里头学问还真不少,要是用不好,效率那叫一个惨不忍睹,代码写出来也像一坨浆糊。今儿个,咱就掰扯掰扯,在Python里到底怎么排序这档子事儿。

你刚上手Python,可能最先接触的就是列表(List)。列表排序,这太直观了不是?Python给你准备了个现成的招儿:list.sort() 方法。瞧,直接在列表对象上调用,它就“原地”给你排好了。比如你有个数字列表 nums = [3, 1, 4, 1, 5, 9, 2, 6],想让它从小到大,直接 nums.sort() 走你!再打印 nums,嘿,[1, 1, 2, 3, 4, 5, 6, 9],齐活!想倒着排?简单,nums.sort(reverse=True),参数一设,分分钟给你来个逆序。

但等等,这个 sort() 方法,它有个脾气——它是“就地”排序,也就是说,它会直接修改原列表,不给你留个副本。有时候,你可能不希望动原列表,就想拿个排好序的新列表接着用,原列表该是啥样还是啥样。这时候,Python又给你准备了另一招:内置函数 sorted()。这个 sorted() 就乖巧多了,它不挑食,列表、元组、字符串,甚至字典、集合这些迭代对象它都能给你排。最关键的是,它不改变原对象,总是返回一个全新的、排好序的列表。

打个比方,你有个元组 data = (5, 2, 8, 1, 9),元组是不可变的,你不能直接调用 sort()。但你可以 sorted_data = sorted(data)。看看 data,还是 (5, 2, 8, 1, 9),纹丝不动;而 sorted_data 呢,赫然是一个崭新的列表 [1, 2, 5, 8, 9]。看到了吧?一个原地修改,一个返回新列表,这俩哥们儿各有各的用武之地,得看你具体的场景选谁。

那要是排序的不是简单的数字或者字符串呢?比如你有一个列表,里面装的是各种商品信息,每个商品是个字典,长这样:products = [{'name': 'Laptop', 'price': 8000, 'stock': 50}, {'name': 'Keyboard', 'price': 500, 'stock': 200}, {'name': 'Mouse', 'price': 200, 'stock': 150}]。现在你想按价格从低到高排序,怎么排序Python这个列表里的字典?直接 sorted(products) 肯定不行,Python不知道该拿字典的哪个部分来比。

这时候,就需要请出 key 参数了。无论是 sort() 方法还是 sorted() 函数,都有个 key 参数,它接收一个函数作为参数。这个函数会作用于列表中的每一个元素,然后排序的时候,就根据这个函数返回的值来比较大小。

要按价格排?没问题!我们可以写个小函数,接收一个商品字典,返回它的价格:def get_price(item): return item['price']。然后调用 sorted(products, key=get_price)。瞧,输出的就是按价格排好序的列表了。

等等,每次都得专门写个小函数给 key,是不是有点麻烦?Python还有更优雅的方式——Lambda表达式。Lambda表达式就是个匿名的小函数,写起来更简洁。上面的例子用Lambda可以这么写:sorted(products, key=lambda item: item['price'])。哎呀,是不是瞬间觉得代码清爽多了?Lambda表达式在这里简直是神器,随用随写,不用定义具名函数,特别适合这种一次性的简单操作。

要是我想先按价格排,价格一样的再按库存排呢?怎么排序Python能实现多级排序?这也能办到!key 函数不仅仅能返回一个值,它还能返回一个元组。Python在比较元组的时候,会先比较第一个元素,第一个元素相等再比较第二个,以此类推。所以,要先按价格升序,再按库存降序(库存多的排前面),我们可以让 key 函数返回 (价格, -库存)。为啥是 -库存 呢?因为默认是升序,要降序就得取个负号,让大的变成小的,小的变成大的,这样升序排序时,原本大的反而会排在前面。

来,看看代码:sorted(products, key=lambda item: (item['price'], -item['stock']))。这行代码就告诉你怎么排序Python实现多级排序了。它会先看价格,价格低的在前;如果价格一样,就看库存的负值,负值大的(也就是库存少的)反而排在后面,负值小的(也就是库存多的)排在前面,这不就实现了库存的降序排列嘛!妙不妙?

除了列表里的字典,你可能还会遇到给字典本身排序的情况。比如一个字典 scores = {'Alice': 85, 'Bob': 92, 'Charlie': 78, 'David': 92}。字典本身是无序的(在Python 3.7+版本后,字典保持插入顺序,但这不叫排序),你想按分数高低,或者按名字字母顺序来处理这个字典。

记住,字典本身是无序集合,你不能直接对字典进行排序。但是,你可以获取字典的键(keys)、值(values)或者键值对(items),然后对这些列表进行排序,最后再根据排好的顺序来处理字典的数据。

比如,你想按分数高低获取名字列表。你可以这么干:sorted(scores, key=lambda name: scores[name], reverse=True)。这里 sorted() 作用于字典的键(默认行为),key 函数则根据键去字典里查找对应的值(分数)来作为排序依据。reverse=True 表示降序,也就是分数高的在前。这样你就得到一个按分数从高到低排列的名字列表:['Bob', 'David', 'Alice', 'Charlie']。你看,分数都是92的Bob和David,谁在前谁在后?这取决于原始字典中它们的相对位置(对于3.7+),或者是不确定顺序(对于3.6-)。

如果你想获得一个按分数排序后的键值对列表,方便后续处理,可以对 scores.items() 进行排序。scores.items() 会返回一个包含所有键值对的列表,每个键值对是一个元组 (键, 值)

sorted(scores.items(), key=lambda item: item[1], reverse=True)。这里的 key 函数 lambda item: item[1] 表示用元组的第二个元素(也就是分数)来排序。结果会是一个列表,长这样:[('Bob', 92), ('David', 92), ('Alice', 85), ('Charlie', 78)]。这下,按分数高低排好的键值对就一目了然了。

再多说一句,关于性能。对于简单的数字或字符串排序,Python内置的排序算法(Timsort,一种混合排序算法)效率非常高,通常情况下你不需要过度担心性能问题。但如果你的列表非常大,或者 key 函数的计算成本很高,那么性能就可能成为一个考虑因素。不过对于绝大多数日常开发来说,直接使用 sort()sorted() 配合 key 参数已经绰绰有余了。

理解怎么排序Python的核心在于掌握 sort()sorted() 的区别,以及如何灵活运用 key 参数。key 参数就像是给排序算法指路,告诉它“别看元素本身长啥样,就看我key函数算出来的值!” 这个“看”的方式决定了排序的结果。学会用Lambda表达式配合 key 参数,能让你的代码更紧凑,更具Pythonic风格。

总而言之,Python在排序这事儿上给的选择挺多,从最简单的原地排序 sort() 到返回新列表的 sorted(),再到用 key 参数玩转各种复杂对象的排序,甚至是多级排序,它都给你安排得明明白白。所以下次再问怎么排序Python某个对象,先想想它是啥类型,想原地改还是拿新列表,需要基于啥规则排序,然后对号入座,用合适的工具和方法,写出既正确又漂亮的排序代码吧。熟练掌握这些,你的Python功力肯定噌噌往上涨。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。