使用多个属性对 Python 列表进行排序

2024 年 8 月 29 日 | 阅读 6 分钟

Python 列表的排序方式有很多种。有各种各样的算法可以用来排序列表。排序一维 Python 列表非常直接。它只需要直接应用其中一种可用算法。然而,给定一个嵌套的 Python 列表,我们将根据什么来排序这个列表?让我们来看看如何解决这个问题。

引言

排序算法通常用于解决与数据结构相关的问题。它们可以应用于任何数据结构。我们可以使用内置的 Python 函数来排序任何 Python 列表。内置的 sort() 函数会就地排序列表,而另一个函数 sorted() 则返回一个已排序的列表。然而,如果我们只使用该函数并将列表作为其参数传递,我们只能根据一个属性进行排序。因此,如果我们希望根据多个属性对嵌套的 Python 列表进行排序,我们必须寻找其他方法。

使用多个属性对 Python 列表进行排序的方法

使用多个属性排序列表有几个好处。此操作相当于根据第一列对属性进行分组,对其进行排序,然后单独对每一列的属性进行排序。假设我们有一个嵌套的 Python 列表,需要对其进行排序。如果我们根据嵌套列表的第一个元素进行排序,并且有两个元素相同,那么这两个列表的顺序将是不确定的。然后我们必须查找第二个元素、第三个元素,依此类推。

排序列表的方法

  • 使用 sort() 函数和 lambda 函数
  • 使用 itemgetter
  • 使用 attrgetter

方法 1

如前所述,可以使用内置的 sorted() 函数对 Python 列表进行排序。然而,该函数的默认行为是根据单个属性对列表进行排序。我们可以向列表添加一个额外的参数,以便使用此函数根据多个属性对列表进行排序。这个参数称为“key”。函数的语法如下:

语法

首先,我们将定义一个嵌套的 Python 列表。

下一步是使用 sorted() 函数对嵌套列表进行排序。在该函数中,我们将列表作为参数之一。第二个参数是 key。key 是一个用于排序列表的函数。我们将以语法所示的方式给出 lambda 函数。first_column_index 是决定排序顺序的主列。然后将根据 second_column_index 对每个组进行排序。我们可以根据需要提供任意数量的列。

该函数将返回排序后的列表。最后一步是打印排序后的列表。

让我们看一个例子来理解函数的工作原理。我们将创建一个包含整数和字符串的嵌套 Python 列表。我们将根据多列属性对列表进行排序。

代码

输出

[[2, 'Andrew', 'Actor', 30], [4, 'Harry', 'Singer', 29], [1, 'Harry', 'Singer', 32], [3, 'Tom', 'Actor', 28], [5, 'Tom', 'Director', 30]]

正如我们所见,“Tom”在第一列中对于两行是相同的。根据函数,如果两行或多行的第一列值相同,那么这些行将根据第二列进行排序。因此,“Actor”排在“Director”之前。现在,索引为 0 和 3 的行的第二列索引值相同。因此,这些行将根据第三列索引进行排序。

时间复杂度:该函数的时间复杂度为 O(log n)。但是,我们对整个列表进行了多次排序;因此,对嵌套列表进行排序的时间复杂度为 O(n * log n)。

空间复杂度:我们将排序后的列表存储在另一个变量中;因此,空间复杂度为 O(n)

方法 - 2

在此方法中,我们将使用 itemgetter 函数。我们将再次将该函数与 sorted 函数一起使用。此函数允许我们使用尽可能多的属性来排序列表。该函数的工作方式类似于 lambda 函数;这次,我们需要给函数一个指向该项的指针。

让我们看一下 itemgetter 的语法

要使用 itemgetter 函数,我们需要导入 operator 库。导入库后,下一步是创建一个嵌套列表。我们将根据 3 列对这个嵌套列表进行排序。我们将使用 sorted 函数来提供列表名称,并再次使用 key 参数。对于此参数,我们将提供 itemgetter 函数以及列索引,就像 lambda 函数一样。最后,我们将打印排序后的列表。

我们将使用第一个示例中使用的相同的嵌套列表。我们将根据第一、第二和第三列索引对列表进行排序。正如我们所见,“Tom”在第一列中对于两行是相同的。根据函数,如果两行或多行的第一列值相同,那么这些行将根据第二列进行排序。因此,“Actor”排在“Director”之前。现在,索引为 0 和 3 的行的第二列索引值相同。因此,这些行将根据第三列索引进行排序。

代码

输出

[[2, 'Andrew', 'Actor', 30], [4, 'Harry', 'Singer', 29], [1, 'Harry', 'Singer', 32], [3, 'Tom', 'Actor', 28], [5, 'Tom', 'Director', 30]]

时间复杂度:排序函数必须多次对列表进行排序。对列表进行一次排序的时间复杂度为 O(log n)。但是,对列表进行 n 次排序将使时间复杂度为 O(n log n),其中 n 是列表元素的数量。

空间复杂度:我们使用了空间来存储排序后的列表。由于原始列表占用的空间为 O(n),因此排序后的列表也将占用 O(n) 的空间。

方法 - 3

在此方法中,我们使用 attrgetter() 函数根据多个属性对列表进行排序。我们必须导入 operator 模块才能使用 attrgetter() 方法。此外,我们不能将列索引传递给此方法;因此,我们首先需要为嵌套列表的列命名。

代码

输出

[[2, 'Andrew', 'Actor', 30], [4, 'Harry', 'Singer', 29], [1, 'Harry', 'Singer', 32], [3, 'Tom', 'Actor', 28], [5, 'Tom', 'Director', 30]]

下一主题Alteryx vs Python