Python List sort()方法

时间:2020-02-23 14:43:20  来源:igfitidea点击:

Python List sort()方法以自然顺序对列表元素进行排序。
排序就地进行,因此列表被修改。

Python具有内置函数sorted(),该函数用于从可迭代对象创建排序列表。

1. Python排序列表(自然顺序)

当我们对数字列表进行排序时,自然的排序是按照升序对它们进行排序。

numbers_list = [3.4, 5.1, 2.2, 4.1, 1.0, 3.8]

print(f'Before sorting: {numbers_list}')

numbers_list.sort()

print(f'After sorting: {numbers_list}')

输出:

Before sorting: [3.4, 5.1, 2.2, 4.1, 1.0, 3.8]
After sorting: [1.0, 2.2, 3.4, 3.8, 4.1, 5.1]

推荐阅读:Python f字符串

默认排序也针对字符串实现。
这是一个对字符串列表进行排序的简单示例。

str_list = ['a', 'c', 'd', 'b', 'B', 'C', '1']
str_list.sort()
print(str_list)  # ['1', 'B', 'C', 'a', 'b', 'c', 'd']

2.以相反的顺序对列表进行排序

如果您希望以相反的顺序进行排序,请将reverse参数传递为True。
我们可以使用它来按降序对数字列表进行排序。

numbers_list = [3.4, 5.1, 2.2, 4.1, 1.0, 3.8]

print(f'Before sorting: {numbers_list}')

numbers_list.sort(reverse=True)

print(f'After sorting: {numbers_list}')

输出:

Before sorting: [3.4, 5.1, 2.2, 4.1, 1.0, 3.8]
After sorting: [5.1, 4.1, 3.8, 3.4, 2.2, 1.0]

3.对嵌套列表进行排序

如果我们在嵌套列表上调用sort()函数,则仅使用列表元素中的前几个元素进行排序。
让我们用一个简单的例子来理解这一点。

numbers = [[1, 2], [2, 1], [4, 3], [5, 2], [3, 3]]

print(f'Before sorting: {numbers}')

numbers.sort()

print(f'After sorting: {numbers}')

输出:

Before sorting: [[1, 2], [2, 1], [4, 3], [5, 2], [3, 3]]
After sorting: [[1, 2], [2, 1], [3, 3], [4, 3], [5, 2]]

很明显,排序是基于嵌套列表中的第一个元素进行的。

但是,有时我们想根据不同元素的位置对嵌套列表进行排序。

假设嵌套列表包含有关人员姓名,年龄和性别的信息。
让我们看看如何根据年龄对嵌套列表进行排序,这是嵌套列表中的第二个元素。

def custom_key(people):
  return people[1]  # second parameter denotes the age

persons = [['Alice', 26, 'F'], ['Trudy', 25, 'M'], ['Bob', 25, 'M'], ['Alexa', 22, 'F']]

print(f'Before sorting: {persons}')

persons.sort(key=custom_key)

print(f'After sorting: {persons}')

输出:

Before sorting: [['Alice', 26, 'F'], ['Trudy', 25, 'M'], ['Bob', 25, 'M'], ['Alexa', 22, 'F']]
After sorting: [['Alexa', 22, 'F'], ['Trudy', 25, 'M'], ['Bob', 25, 'M'], ['Alice', 26, 'F']]

我们使用key参数来指定要用于排序目的的元素。
custom_key函数返回用于对列表进行排序的键。

4.自定义逻辑对列表进行排序

我们还可以实现自己的逻辑来对列表元素进行排序。

在最后一个示例中,我们使用age作为对列表进行排序的关键元素。

但是有句俗话,"女士优先!"。

因此,我们希望对列表进行排序,使女性优先于男性。
如果两个人的性别相匹配,则年龄较小的人将获得更高的优先级。

因此,我们必须在我们的排序函数中使用key参数。
但是比较功能需要转换为键。

因此,我们需要导入一个名为functools的库。
我们将使用功能cmp_to_key()将比较功能转换为键。

import functools

def compare_function(person_a, person_b):
  if person_a[2] == person_b[2]:  # if their gender become same
      return person_a[1] - person_b[1]  # return True if person_a is younger
  else:  # if their gender not matched
      if person_b[2] == 'F':  # give person_b first priority if she is female
          return 1
      else:  # otherwise give person_a first priority
          return -1

persons = [['Alice', 26, 'F'], ['Trudy', 25, 'M'], ['Bob', 24, 'M'], ['Alexa', 22, 'F']]

print(f'Before sorting: {persons}')

persons.sort(key=functools.cmp_to_key(compare_function))

print(f'After sorting: {persons}')

输出:

Before sorting: [['Alice', 26, 'F'], ['Trudy', 25, 'M'], ['Bob', 24, 'M'], ['Alexa', 22, 'F']]
After sorting: [['Alexa', 22, 'F'], ['Alice', 26, 'F'], ['Bob', 24, 'M'], ['Trudy', 25, 'M']]

该列表首先基于性别进行排序。
然后根据人员年龄进行排序。

5.排序对象列表

默认排序适用于数字和字符串。
但是,它不适用于自定义对象列表。

让我们看看当尝试对对象列表进行默认排序时会发生什么。

class Employee:

  def __init__(self, n, a, gen):
      self.name = n
      self.age = a
      self.gender = gen

  def __str__(self):
      return f'Emp[{self.name}:{self.age}:{self.gender}]'

  # List uses __repr__, so overriding it to print useful information
  __repr__ = __str__

e1 = Employee('Alice', 26, 'F')
e2 = Employee('Trudy', 25, 'M')
e3 = Employee('Bob', 24, 'M')
e4 = Employee('Alexa', 22, 'F')

emp_list = [e1, e2, e3, e4]

print(f'Before Sorting: {emp_list}')

try:
  emp_list.sort()
except TypeError as te:
  print(te)

输出:

Before Sorting: [Emp[Alice:26:F], Emp[Trudy:25:M], Emp[Bob:24:M], Emp[Alexa:22:F]]
'<' 不支持 between instances of 'Employee' and 'Employee'

在这种情况下,我们必须强制提供键功能来指定要用于排序的对象的字段。

# sorting based on age
def sort_by_age(emp):
  return emp.age

emp_list.sort(key=sort_by_age)
print(f'After Sorting By Age: {emp_list}')

输出:

After Sorting By Age: [Emp[Alexa:22:F], Emp[Bob:24:M], Emp[Trudy:25:M], Emp[Alice:26:F]]

我们还可以利用functools模块为列表元素创建自定义排序逻辑。