用 Python 进行排序的终极指南

点击关注我哦

欢迎关注 “小白玩转Python”,发现更多 “有趣”

在本教程中,我们将研究如何根据不同的标准对迭代对象(如列表、元组、字符串和字典)进行排序。

对列表进行排序

有两种方法对列表进行排序。我们可以使用 sort()方法或 sorted()函数。sort()方法只能在list上使用。sorted()函数可以在任何迭代对象上使用。

sort()方法

sort()方法是一个就地修改列表并返回None的list 方法。换句话说,sort()方法修改或更改它所调用的列表,而不创建新列表。

sort()方法有两个可选参数:key参数和reverse参数。key参数接受一个带有单个参数的函数,并返回用于排序的key。默认情况下,sort()方法将按数字的值和字符串的字母顺序对列表进行排序。reverse参数接受布尔值True或False。reverse的默认值为False,这意味着它按升序排序。为了按降序排序,我们将设置reverse=True。当我们看下面的一些例子时,这些参数将更有意义。

对数字列表进行排序

假设有一个数字列表num_list,我们想按升序排序。

num_list = [1,-5,3,-9,25,10]
num_list.sort()
print(num_list)
# [-9,-5,1,3,10,25]

在这个列表中调用 sort()方法。注意,我们没有为key参数传入值。因此,它只是按照数字的实际值对这个数字列表进行排序。因为我们没有设置reverse = True,所以它是按升序排序的。sort()方法修改了num_list。

如果我们想要根据数字的绝对值对列表进行排序会怎样?这时我们需要使用key参数。key参数接受一个函数,该函数接受一个参数,并返回一个用于排序的key。

num_list = [1,-5,3,-9,25,10]
def absolute_value(num):
    return abs(num)
num_list.sort(key = absolute_value)
print(num_list) 
# [1,3,-5,-9,10,25]

我们定义了一个函数(absolute_value),它接受一个数字并返回它的绝对值。然后,我们将这个函数作为 sort ()方法的key参数的参数传入。因此,在进行比较之前,它通过absolute_value函数处理 num _ list 的每个元素或数字。最终,将获得按照数字的绝对值升序进行排序的结果(因为 reverse 默认设置为 False)。

使用lambda表达式

我们可以用 lambda 表达式代替key参数,如下所示:

num_list.sort(key = lambda num: abs(num))

请记住,sort()方法返回None。因此,如果将sort()方法的输出或返回值设置为新变量,则将得到None,如下所示:

new_list = num_list.sort(key = absolute_value)
print(new_list)
# None

使用内置函数

不必像上面那样编写我们自己的绝对值函数,我们可以直接为key参数传入 python 内置 abs ()函数,如下所示:

num_list.sort(key = abs)

sorted() 函数

Sorted ()函数可以接受三个参数: iterable、 key 和 reverse。换句话说,sort ()方法只适用于列表,但 sorted ()函数可以适用于任何可迭代的对象,如列表、元组、字典等。然而,与返回 None 并修改原始列表的 sort ()方法不同,sorted ()函数返回一个新列表,而原始对象保持不变。

下面让我们重新对num_list使用绝对值排序,但是通过sorted()函数:

num_list = [1,-5,3,-9,25,10]
new_list = sorted(num_list, key = abs)
print(new_list) 
# [1,3,-5,-9,10,25]
print(num_list)
# [1,-5,3,-9,25,10]

我们将可迭代的num_list传递给 sorted()函数,并将内置的abs函数传递给 key 参数。我们将sorted()函数的输出设置为一个新变量new_list。而且num_list 是保持不变的,因为sorted()函数不会修改它所要排序的迭代对象。

注意: 无论向sorted()函数传入什么迭代对象,它总是返回一个列表。

对元组列表进行排序

假设我们有一个元组列表。列表中的每个元素都是一个元组,其中包含三个元素: name、 age 和 salary。

list_of_tuples = [
    ('john', 27, 45000),
    ('jane', 25, 65000),
    ('beth', 31, 70000)
]

我们可以按字母顺序,年龄或薪水对列表进行排序。我们可以使用key参数指定要使用的参数。

要按年龄排序,我们可以使用以下代码:

sorted_age_list = sorted(list_of_tuples, key = lambda person: person[1])
print(sorted_age_list) 
# [('jane', 25, 65000), ('john', 27, 45000), ('beth', 31, 70000)]

list_of_tuples的每个元素都作为person参数传递给lambda表达式,并返回每个元组的索引1处的元素,也就是用于对列表进行排序的值,即年龄。

要按字母顺序对名称进行排序,我们可以完全不传递key,因为默认每个元组的第一个元素就是要进行比较的内容(请记住,默认情况下,字符串按字母顺序进行排序):

sorted_name_list = sorted(list_of_tuples)
print(sorted_name_list) 
# [('beth', 31, 70000), ('jane', 25, 65000), ('john', 27, 45000)]

当然,我们也可以指定按每个元组的第一个元素排序,如下所示:

sorted_name_list = sorted(list_of_tuples, key = lambda person: person[0])
print(sorted_name_list) 
# [('beth', 31, 70000), ('jane', 25, 65000), ('john', 27, 45000)]

请记住,我们可以将lambda表达式分配给变量(类似于使用def关键字定义函数)。因此,我们可以根据lambda表达式对列表进行排序的标准来组织它们:

name = lambda person: person[0]
age = lambda person: person[1]
salary = lambda person: person[2]
# sort by name
sorted(list_of_tuples, key = name)
# sort by age
sorted(list_of_tuples, key = age)
# sort by salary
sorted(list_of_tuples, key = salary)

Itemgetter()函数

我们可以使用操作符模块中的 itemgetter ()函数,而不是使用 lambda 表达式来访问元组中的name、age或 salary 元素。我们可以通过传入索引来指定在元组中访问哪个元素。列表中的每个元组都传递给 itemgetter ()函数,并根据指定的索引返回该元组中的特定元素。

import operator
# sort by name
sorted(list_of_tuples, key = operator.itemgetter(0))
# sort by age
sorted(list_of_tuples, key = operator.itemgetter(1))
# sort by salary
sorted(list_of_tuples, key = operator.itemgetter(2))

Itemgetter()函数允许多级排序,例如下面的列表:

list_of_tuples = [
 ('john', 27, 45000),
 ('jane', 25, 65000),
 ('joe', 25, 35000),
 ('beth', 31, 70000)
]

注意 jane 和 joe 的年龄是一样的。因此,如果我们想先根据年龄排序这个列表,然后根据薪水排序,我们可以向 itemgetter()函数传入两个值:

print(sorted(list_of_tuples, key=operator.itemgetter(1,2))
# [('joe', 25, 35000), ('jane', 25, 65000), ('john', 27, 45000), ('beth', 31, 70000)]

因为 age 的索引是传入的第一个值,所以它将首先用于对元素进行排序。如果年龄相同,则使用 salary 对元素进行排序。

注意: 操作符模块还具有attrgetter()函数,该函数可用于对具有命名属性的对象进行排序。例如,如果我们编写自己的类和该类的实例化对象,我们可以使用 attrgetter ()函数使用特定的命名属性对这些对象进行排序。我们只需将属性的名称传递给 attrgetter ()函数,然后将该函数传递给sorted()函数的键参数。例如,为了按年龄对对象进行排序,我们将以下内容传递给键参数: key = attrgetter (' age')。

对元组进行排序

对元组进行排序与使用sorted()函数对列表进行排序相同,如前所示。我们不能使用sort()方法,因为它是一个 list 方法。

记住,即使我们将元组传递给 sorted()函数,也会返回一个列表。

num_tuple = (5,2,53,9,25)
sorted_tuple = sorted(num_tuple)
print(sorted_tuple)
# [2,5,9,25,53]

字符串排序

字符串也是可迭代对象。因此,它们也可以使用sorted()函数进行排序。sorted()函数将逐个字符地遍历字符串。默认情况下,sorted()函数将按字母顺序对字符串进行排序。

sorted_string = sorted(‘dinosaur’)
print(sorted_string)
# ['a','d','i','n','o','r','s','u']

请注意sorted()函数如何以字母顺序返回字符列表。

对字典进行排序

字典由键-值对组成,因此,它们可以按键或值进行排序。

假设我们有一本字典,键是名字,值是年龄。

dictionary_of_names = {'beth': 37, 
                       'jane': 32,
                       'john': 41, 
                       'mike': 59
}

如果我们只是将整个字典作为迭代对象传递给sorted()函数,则将获得以下输出:

print(sorted(dictionary_of_names))
# ['beth', 'jane', 'john', 'mike']

使用 items()方法

如果要获取整个字典的排序副本,则需要使用字典的items()方法:

print(dictionary_of_names.items())
# dict_items([('beth', 37), ('jane', 32), ('john', 41), ('mike', 59)])

注意,items()方法如何返回一个dict_items对象,该对象看起来类似于元组列表。dict_items对象是可迭代的,因此它可以迭代形式传递给sorted()函数。

我们可以像前面看到的对元组列表排序一样对 dict _ items 对象进行排序。例如,要按每个元组中的第二个元素排序,也就是 age,我们可以使用以下代码:

sorted_age = sorted(dictionary_of_names.items(), key = lambda kv: kv[1])
print(sorted_age)
# [('jane', 32), ('beth', 37), ('john', 41), ('mike', 59)]

请注意,sorted()函数是如何返回元组列表的,该列表按年龄(或每个元组中的第二个元素)进行排序的。要将这个元组列表转换为一个字典,我们可以使用内置的 dict()函数:

sorted_dictionary = dict(sorted_age)
print(sorted_dictionary)
# {'jane': 32, 'beth': 37, 'john': 41, 'mike': 59}

现在我们有了按年龄排序的字典!

总结

在本文中,我们比较了对列表进行排序时的 sort()方法和 sorted()函数。我们学习了 sort()方法如何修改原始列表,以及 sorted()函数如何返回一个新列表。我们还了解到 sort()方法只能用于列表,但 sorted()函数可以用于任何迭代对象。然后,我们学习了如何对不同类型的迭代对象进行排序并遵循不同的排序标准。

·  END  ·

HAPPY LIFE

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值