Python中使用多个属性实现列表排序的三种方法

我们可以通过多种方式对 Python 列表进行排序。有多种算法可以对列表进行排序。对一维 Python 列表进行排序非常简单。它需要直接应用可用算法之一。然而,给定一个嵌套的 Python 列表,我们将根据什么基础对列表进行排序?让我们看看如何解决这个问题。

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

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

对列表进行排序的方法

  1. 使用 sort() 函数和 lambda 函数
  2. 使用 itemgetter
  3. 使用attrgetter


方法一
正如所讨论的,Python 列表可以使用内置函数sorted() 进行排序。但是,此函数的默认性质是根据​​单个属性对列表进行排序。我们可以向列表添加一个参数,以使用此函数使用多个属性对列表进行排序。该参数称为“关键”。该函数的语法如下:

sorted(name_of_list, key = lambda e: (e[first_column_index], e[second_column_index]))  

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

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

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

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

# 根据多列属性对嵌套的 Python 列表进行排序的 Python 程序  ;
  
# 定义包含整数和字符串的嵌套 Python 列表  ;
listt = [[1, 'Harry', 'Singer', 32],  
     [2, 'Andrew', 'Actor', 30],  
     [3, 'Tom', 'Actor', 28],  
     [4, 'Harry', 'Singer', 29],  
     [5, 'Tom', 'Director', 30]]  
  
# 使用内置的 sorted() 函数和匿名 lambda 函数对嵌套列表进行排序  
# 我们将首先根据第 1 列、第 2 列和第 3 列指数对列表进行排序;
sorted = sorted(listt, key = lambda x: (x[1], x[2], x[3]))  
  
# Printing the sorted list  
print(sorted)  

Output:

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

正如我们所看到的,第一列中的“Tom”对于两行来说是相同的。根据该函数,如果两行或更多行具有第 1 列的值,则这些行将根据第 2 列排序。因此,“演员”位于“导演”之前。现在,索引 0 和 3 处的行的第二列索引具有相同的值。因此,这些行根据第三列索引进行排序。

  • 时间复杂度:函数的时间复杂度为O(log n)。然而,我们对整个列表进行了多次排序;因此,对嵌套列表进行排序的时间复杂度为 O(n * log n)。
  • 空间复杂度:我们将排序后的列表存储在不同的变量中;因此空间复杂度将为 O(n)


方法 - 2
在这种方法中,我们将使用 itemgetter 函数。我们将再次将该函数与排序函数一起使用。该函数将允许我们使用尽可能多的属性对列表进行排序。该函数的工作原理与 lambda 函数类似;这次,我们需要为函数提供一个指向该项目的指针。

让我们看看 itemgetter 的语法

sorted(list_name, key = operator.itemgetter(first_column_index, second_column_index)))  

要使用 itemgetter 函数,我们需要导入操作符库。导入操作符库后,下一步是创建嵌套列表。我们将根据 3 列对嵌套列表进行排序。我们将使用 sorted 函数给出列表名称,并再次使用 key 参数。对于这个参数,我们将使用 itemgetter 函数和作为 lambda 函数的列索引。最后,我们将打印排序后的列表。

我们将使用第一个示例中的嵌套列表。我们将根据第一、第二和第三列索引对列表进行排序。我们可以看到,第 1 列中的 "Tom "在两行中都是相同的。根据该函数,如果有两行或更多行的值都在第 1 列,那么这些行将根据第 2 列进行排序。因此,"演员 "排在 "导演 "之前。现在,位于索引 0 和 3 的行的第二列索引值相同。因此,这些行将根据第三列索引排序。

# 使用 itemgetter 函数根据多个属性对嵌套的 Python 列表进行排序的 Python 程序  
导入所需库函数 
import operator  
  
定义嵌套列表并赋予变量名  ;
listt = [[1, 'Harry', 'Singer', 32],  
     [2, 'Andrew', 'Actor', 30],  
     [3, 'Tom', 'Actor', 28],  
     [4, 'Harry', 'Singer', 29],  
     [5, 'Tom', 'Director', 30]]  
  
# 使用内置的 sorted() 函数和 itemgetter 函数对嵌套列表进行排序  
# 我们将首先按照第 1 列、第 2 列和第 3 列指数对列表进行排序;
sorted_list = sorted(listt, key = operator.itemgetter(1, 2, 3))  
  
# Printing the final sorted list  
print(sorted_list)  


  • 时间复杂性:排序功能必须对列表进行多次排序。对列表进行单次排序的时间复杂度为 O(log n)。然而,如果对丢失的列表进行 n 次排序,时间复杂度将为 O(n log n),其中 n 是列表的元素个数。
  • 空间复杂度:我们使用空间来存储排序后的列表。由于原始列表占用的空间为 O(n),因此排序列表占用的空间也是 O(n)。


方法 - 3
在这种方法中,我们使用 attrgetter() 函数根据多个属性对列表进行排序。我们必须导入操作符模块才能使用 attrgetter() 方法。此外,我们不能为该方法提供列索引;因此,我们首先需要为嵌套列表的列命名。

# Python program to sort a nested Python list according to the multiple attributes using the attrgetter function  
  
# Importing the required library  
import operator  
  
# Defining the class  
class String_rep:  
     
  # 调用构造函数为每一列设置列标题
  def __init__(self, no, name, prof, age):  
    self.no = no  
    self.name = name  
    self.prof = prof  
    self.age = age  
  
  # 以字符串格式返回对象方向
  def __repr__(self):  
    return '[' + str(self.no) + ', ' + self.name + ', ' +self.prof+ ', ' +str(self.age)+ ']'  
  
# 定义嵌套列表并赋予变量名
listt = [[1, 'Harry', 'Singer', 32],  
     [2, 'Andrew', 'Actor', 30],  
     [3, 'Tom', 'Actor', 28],  
     [4, 'Harry', 'Singer', 29],  
     [5, 'Tom', 'Director', 30]]  
  
# 使用 sorted() 函数  
# 和 attrgetter 为多个属性   排序列表;
listt.sort(key = operator.attrgetter('name', 'prof', 'age'))  
  
# Print the sorted list  
print(listt)