在 python 开发中,我们经常需要对列表(list)中的元素进行排序。如果列表中的元素是简单的数字或字符串,可以直接使用 sorted() 或 list.sort() 方法。但如果列表中的元素是字典(dict)或自定义对象(class),并且需要根据某个字段(key)进行排序,该怎么办呢?
本文将详细介绍 python 中如何根据列表中某字段排序,涵盖 字典列表排序、自定义对象排序 以及 高级排序技巧(如多字段排序、降序排序等)。
1. 基础排序:数字和字符串列表
如果列表中的元素是数字或字符串,可以直接使用 sorted() 或 list.sort():
numbers = [3, 1, 4, 1, 5, 9, 2] sorted_numbers = sorted(numbers) # 升序 print(sorted_numbers) # [1, 1, 2, 3, 4, 5, 9] numbers.sort(reverse=true) # 降序(原地修改) print(numbers) # [9, 5, 4, 3, 2, 1, 1]
字符串排序:
words = ["banana", "apple", "cherry", "date"] sorted_words = sorted(words) print(sorted_words) # ['apple', 'banana', 'cherry', 'date']
2. 字典列表排序:根据某个键(key)排序
如果列表中的元素是字典,并且需要根据某个键(如 "age"、"score")排序,可以使用 sorted() 的 key 参数。
示例 1:根据字典的某个键排序
students = [
{"name": "alice", "age": 20, "score": 90},
{"name": "bob", "age": 18, "score": 85},
{"name": "charlie", "age": 22, "score": 95}
]
# 按 age 升序排序
sorted_by_age = sorted(students, key=lambda x: x["age"])
print(sorted_by_age)
"""
[
{'name': 'bob', 'age': 18, 'score': 85},
{'name': 'alice', 'age': 20, 'score': 90},
{'name': 'charlie', 'age': 22, 'score': 95}
]
"""
# 按 score 降序排序
sorted_by_score_desc = sorted(students, key=lambda x: x["score"], reverse=true)
print(sorted_by_score_desc)
"""
[
{'name': 'charlie', 'age': 22, 'score': 95},
{'name': 'alice', 'age': 20, 'score': 90},
{'name': 'bob', 'age': 18, 'score': 85}
]
"""
示例 2:使用operator.itemgetter替代lambda
operator.itemgetter 可以替代 lambda,提高性能(适用于大数据量):
from operator import itemgetter
# 按 name 排序
sorted_by_name = sorted(students, key=itemgetter("name"))
print(sorted_by_name)
"""
[
{'name': 'alice', 'age': 20, 'score': 90},
{'name': 'bob', 'age': 18, 'score': 85},
{'name': 'charlie', 'age': 22, 'score': 95}
]
"""
3. 自定义对象排序:根据属性排序
如果列表中的元素是自定义类的对象,并且需要根据某个属性(如 age、score)排序,可以使用 sorted() 的 key 参数或实现 __lt__ 方法。
示例 1:使用lambda按属性排序
class student:
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
def __repr__(self):
return f"student(name={self.name}, age={self.age}, score={self.score})"
students = [
student("alice", 20, 90),
student("bob", 18, 85),
student("charlie", 22, 95)
]
# 按 age 排序
sorted_by_age = sorted(students, key=lambda x: x.age)
print(sorted_by_age)
"""
[
student(name=bob, age=18, score=85),
student(name=alice, age=20, score=90),
student(name=charlie, age=22, score=95)
]
"""
示例 2:实现__lt__方法(推荐)
如果经常需要按某个属性排序,可以在类中实现 __lt__(小于)方法,这样可以直接使用 sorted() 或 list.sort():
class student:
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
def __lt__(self, other):
return self.age < other.age # 按 age 升序排序
def __repr__(self):
return f"student(name={self.name}, age={self.age}, score={self.score})"
students = [
student("alice", 20, 90),
student("bob", 18, 85),
student("charlie", 22, 95)
]
# 直接排序(无需 key 参数)
sorted_students = sorted(students)
print(sorted_students)
"""
[
student(name=bob, age=18, score=85),
student(name=alice, age=20, score=90),
student(name=charlie, age=22, score=95)
]
"""
如果需要按不同属性排序,可以动态修改 __lt__ 或使用 functools.cmp_to_key(较复杂,不推荐)。
4. 高级排序技巧
多字段排序
如果需要先按 age 排序,再按 score 排序,可以使用 tuple 作为 key:
students = [
{"name": "alice", "age": 20, "score": 90},
{"name": "bob", "age": 18, "score": 85},
{"name": "charlie", "age": 20, "score": 95},
{"name": "david", "age": 18, "score": 80}
]
# 先按 age 升序,再按 score 降序
sorted_students = sorted(
students,
key=lambda x: (x["age"], -x["score"]) # 负号实现降序(仅适用于数字)
)
# 或者更通用的方式:
sorted_students = sorted(students, key=lambda x: (x["age"], x["score"]), reverse=false) # 先 age 升序,再 score 升序
# 如果需要 age 升序,score 降序,可以分两步排序:
students.sort(key=lambda x: x["score"], reverse=true) # 先按 score 降序
students.sort(key=lambda x: x["age"]) # 再按 age 升序(稳定排序)
print(sorted_students)
"""
[
{'name': 'david', 'age': 18, 'score': 80},
{'name': 'bob', 'age': 18, 'score': 85},
{'name': 'alice', 'age': 20, 'score': 90},
{'name': 'charlie', 'age': 20, 'score': 95}
]
"""
降序排序
使用 reverse=true 实现降序:
numbers = [3, 1, 4, 1, 5, 9, 2] sorted_desc = sorted(numbers, reverse=true) print(sorted_desc) # [9, 5, 4, 3, 2, 1, 1]
自定义排序逻辑(functools.cmp_to_key)
如果排序逻辑较复杂(如按字符串长度排序),可以使用 functools.cmp_to_key:
from functools import cmp_to_key
words = ["banana", "apple", "cherry", "date"]
# 自定义比较函数:按字符串长度排序
def compare(a, b):
if len(a) < len(b):
return -1
elif len(a) > len(b):
return 1
else:
return 0
sorted_words = sorted(words, key=cmp_to_key(compare))
print(sorted_words) # ['date', 'apple', 'banana', 'cherry']
5. 总结
| 排序场景 | 方法 | 示例 |
|---|---|---|
| 数字/字符串列表排序 | sorted() 或 list.sort() | sorted([3, 1, 4]) |
| 字典列表按某键排序 | sorted(list, key=lambda x: x["key"]) | sorted(students, key=lambda x: x["age"]) |
| 自定义对象按属性排序 | sorted(list, key=lambda x: x.attr) 或 __lt__ | sorted(students, key=lambda x: x.age) |
| 多字段排序 | sorted(list, key=lambda x: (x["key1"], x["key2"])) | sorted(students, key=lambda x: (x["age"], x["score"])) |
| 降序排序 | reverse=true | sorted(numbers, reverse=true) |
| 复杂排序逻辑 | functools.cmp_to_key | sorted(words, key=cmp_to_key(compare)) |
推荐做法:
- 优先使用
sorted()(非原地排序)或list.sort()(原地排序)。 - 字典列表排序推荐
lambda或operator.itemgetter。 - 自定义对象排序推荐实现
__lt__方法。 - 多字段排序推荐使用
tuple作为key。
到此这篇关于从基础到进阶详解python如何根据列表中某字段排序的文章就介绍到这了,更多相关python列表排序内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论