Python 排序详解

Python中列表中有一个内置方法sort()方法,可以直接对列表进行修改;还有一个sorted()方法,它会从一个可迭代对象构建一个新的列表

基本排序

简单的升序非常简单,只需调用sorted()方法,直接返回一个新列表

li1 = [3, 1, 8, 39, 4, 89]
li2 = sorted(li1)
print(li2)

# 输出:[1, 3, 4, 8, 39, 89]

也可以直接使用list.sort(),会直接修改列表

li1 = [3, 1, 8, 39, 4, 89]
li1.sort()
# li2 = sorted(li1)
print(li1)

还有一个区别,list.sort()方法只是为列表定义的;而sorted()可以对所有可迭代对象进行排序,但只会返回一个列表

Key关键字

list.sort()和sorted()都有一个形参Key,来指定在进行比较之前要在每个列表元素调用的函数

li = sorted('This is a test string from Wang'.split(), key=str.lower)
print(li)
# 输出:['a', 'from', 'is', 'string', 'test', 'This', 'Wang']

key形参的值应该是一个函数,它接受一个参数并返回一个用于排序的键,这种技巧很快,因为对于每个输入记录只会调用一次key函数。

一种常见的操作是使用对象的一些索引作为键对复杂对象进行排序

student_tuple = [
    ('john', 'S', '16'),
    ('tom', '2S', '20'),
    ('jemmy', 'SB', '18'),
    ('ming', 'SS', '13')
]
print(sorted(student_tuple, key=lambda student: student[2]))

# 输出:[('ming', 'SS', '13'), ('john', 'S', '16'), ('jemmy', 'SB', '18'), ('tom', '2S', '20')]

字典排序

student_info = {
    'Tom': ['male', '15', 'A'],
    'Jim': ['female', '17', 'A+'],
    'Alice': ['male', '20', 'B+']
}

print(sorted(student_info.items(), key=lambda x: x[1][1])) # 按照字典值的第二个元素排序
                                                           # x相当于字典遍历出来的一个键值元祖
student_info = [
    {'name':'tom', 'age': '15', 'grade':'A'},
    {'name':'Jim', 'age': '17', 'grade':'A++'},
    {'name':'Alice', 'age': '20', 'grade':'B+'},
]

print(sorted(student_info, key=lambda key: key['age']))

 同样适用于具有命名属性的对象

class Student:
    def __init__(self, name, grade, age):
        self.name = name
        self.grade = grade
        self.age = age

    def __repr__(self):
        return repr((self.name, self.grade, self.age))

student_tuple = [
    Student('john', 'A', '14'),
    Student('tom', 'B', '20'),
    Student('jemmy', 'B+', '18'),
    Student('ming', 'B-', '16')
]
print(sorted(student_tuple, key=lambda x:x.age))
# 输出:[('john', 'A', '14'), ('ming', 'B-', '16'), ('jemmy', 'B+', '18'), ('tom', 'B', '20')]

Operator模块函数

operator函数包含itemgetter()和attrgetter(),使用这些函数上述例子会更加简单

from operator import itemgetter
student_tuple = [
    ('john', 'S', '16'),
    ('tom', '2S', '20'),
    ('jemmy', 'SB', '18'),
    ('ming', 'SS', '13')
]
print(sorted(student_tuple, key=itemgetter(2)))

student_tuple = [
    Student('john', 'A', '16'),
    Student('tom', 'B', '20'),
    Student('jemmy', 'B+', '18'),
    Student('ming', 'B-', '16')
]
print(sorted(student_tuple, key=attrgetter('age')))

 

operator模块还允许多级排序,例如按照年龄排序,然后按照名字排序

from operator import itemgetter
student_tuple = [
    ('john', 'S', '16'),
    ('tom', '2S', '20'),
    ('jemmy', 'SB', '18'),
    ('ming', 'SS', '16')
]
print(sorted(student_tuple, key=itemgetter(2, 0)))
 # 输出:[('john', 'S', '16'), ('ming', 'SS', '16'), ('jemmy', 'SB', '18'), ('tom', '2S', '20')]

升序和降序

list.sort()和sorted()接受布尔值reverse参数,用于标记升序降序;reverse为True降序,False升序

排序的稳定性和排序复杂度

排序稳定性指多个元素具有相同的键值时,将保留原来的顺序

data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
print(sorted(data, key=itemgetter(0)))
# 输出:[('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]

这样就可以允许我们进行一系列排序步骤中构建复杂的排序,例如:要先按照age降序,然后在按照名字升序

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值