乐趣区

关于人工智能:Python相关数据结构的排序

作者 |Luay Matalka
编译 |VK
起源 |Towards Datas Science

在本教程中,咱们将理解如何依据不同的规范对可迭代的容器 (如列表、元组、字符串和字典) 进行排序。

对列表排序

有两种办法能够对列表进行排序。咱们能够应用 sort()办法或 sorted()函数。sort()办法是一个列表办法,因而只能用于列表。sorted()函数实用于任何容器。

sort()办法

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

sort()办法有两个可选参数:key 参数和 reverse 参数。key 参数承受一个承受单个参数并返回用于排序的键的函数。

默认状况下,sort()办法将按数字的值和字符串的字母程序对列表进行排序。reverse 参数承受布尔值 True 或 False。reverse 的默认值为 False,这意味着它按升序排序。为了按降序排序,咱们将设置 reverse=True。当咱们看上面的一些例子时,这些参数将更有意义。

对数字列表排序

假如咱们有一个数字列表,咱们想按升序排序。

num_list = [1,-5,3,-9,25,10]

num_list.sort()

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

所以咱们有一个 num_list 列表,咱们对此列表调用 sort()办法。请留神,咱们没有为键参数传递值。因而,它只是依据理论值对这个 num_list 进行排序。因为咱们没有设置 reverse=True,所以它按升序排序。sort()办法批改了num_list

如果咱们想依据数字的绝对值对列表进行排序呢?这时咱们须要应用 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()办法的键参数的参数传入。因而,在进行比拟之前,它通过绝对值函数运行 num_list 的每个元素或数字。因而,这些数字的绝对值将用于按升序对该列表进行排序(因为 reverse 默认设置为 False)。

应用 lambda 表达式

咱们能够为键参数传入 lambda 表达式,如下所示:

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

请在此处查看无关 lambda 表达式的教程:

https://towardsdatascience.co…

请记住,sort()办法返回 None。因而,如果咱们将 sort()办法的输入或返回值设置为一个新变量,则如下所示:

new_list = num_list.sort(key = absolute_value)

print(new_list)
# None

应用内置函数

咱们不用像下面那样编写咱们本人的绝对值函数,而只需为键参数传入 python 内置的 abs()函数,如下所示:

num_list.sort(key = abs)

sorted()函数

sorted()函数能够承受三个参数:容器、key 和 reverse。sorted()函数能够解决任何可迭代的容器,例如列表、元组、字典等。然而,与 sort()办法不同的是 sort()办法返回 None 并批改原始列表,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()函数的容器是什么,它总是返回一个列表。

排序元组列表

假如咱们有一个元组列表。列表的每个元素都是一个元组,蕴含三个元素:姓名、年龄和薪水。

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

咱们能够按字母程序,按年龄,或按薪水来排序。咱们能够指定要与键参数一起应用的对象。

要按年龄排序,咱们能够应用以下代码:

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 处返回。这是用于对列表排序的值,即年龄。

为了按字母程序对名称进行排序,咱们能够在不传递任何键的状况下执行此操作,因为默认状况下,每个元组的第一个元素是被比拟的(记住,默认状况下,字符串是按字母程序排序的):

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]

#按名称排序
sorted(list_of_tuples, key = name)

#按年龄排序
sorted(list_of_tuples, key = age)

#按薪资排序
sorted(list_of_tuples, key = salary)

itemgetter()函数

咱们能够应用 operator 模块中的 itemgetter()函数,而不是应用 lambda 表达式从元组中拜访 name、age 或 salary 元素。

咱们能够通过传入索引来指定要拜访元组中的哪个元素。列表中的每个元组都被传递给 itemgetter()函数,并依据指定的索引返回该元组中的特定元素。

import operator

#按名称排序
sorted(list_of_tuples, key = operator.itemgetter(0))

#按年龄排序
sorted(list_of_tuples, key = operator.itemgetter(1))

#按薪资排序
sorted(list_of_tuples, key = operator.itemgetter(2))

函数的作用是:容许多级排序。例如,假如咱们有一个元组列表:

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 对元素进行排序。

还能够应用名为 attr()的属性对 getter()进行排序。例如,如果咱们编写了本人的类并实例化了该类的对象,则能够应用 attrgetter()函数应用特定的命名属性对这些对象进行排序。

咱们只需将属性的名称传递给 attrgetter()函数,而后将该函数传递到 sorted()函数的键参数中。例如,为了按年龄对对象排序,咱们将把以下内容传递给 key 参数:key = attrgetter(‘age’).。

对元组排序

对元组进行排序与应用 sorted()函数对列表排序雷同。此外,因为元组是不可变的对象,因而咱们不能应用 sort()办法,因为 sort()办法批改了原始列表。

请记住,即便咱们将元组传递给 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()函数如何按字母程序返回字符列表。

对字典排序

字典由 key:value 对组成。因而,能够按键或值进行排序。

假如咱们有一个字典,键是名字,值是年龄。

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

如果咱们只是将整个字典作为容器传递给 sorted()函数,咱们将失去以下输入:

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

如咱们所见,如果咱们将整个字典作为容器传递给 sorted()函数,它将返回一个只蕴含按字母程序排序的键的列表。

应用 items()办法

如果要获取整个字典的排序正本,则须要应用 dictionary items()办法:

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

请留神 items()办法如何返回 dict_items 对象,该对象看起来相似于元组列表。这个 dict_items 对象是一个容器,它能够作为容器传递给 sorted()函数。

咱们能够像对后面看到的元组列表排序一样,对 dict_items 对象进行排序。例如,要按每个元组中的第二个元素 (即年龄) 进行排序,能够应用以下代码:

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()函数能够解决任何容器。而后咱们学习了如何对不同类型的容器进行排序并应用不同的规范。

原文链接:https://towardsdatascience.co…

欢送关注磐创 AI 博客站:
http://panchuang.net/

sklearn 机器学习中文官网文档:
http://sklearn123.com/

欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/

退出移动版