python实现元组类型和自定义类型的多重排序(多级排序)使用优先级队列实现(heapq堆队列算法实现最小堆)

参考链接: python实现多重排序(多级排序)
参考链接: Python中优先级队列的实现,heapq堆队列算法实现最小堆
参考链接: Python内置函数sorted()和列表的sort方法使用介绍
参考链接: Python中优先级队列的实现,heapq堆队列算法实现最小堆
参考链接: 排序指南
参考链接: sorted(iterable, *, key=None, reverse=False)
参考链接: sort(*, key=None, reverse=False)
参考链接: Operator 模块函数
参考链接: 使用 cmp 参数的旧方法
参考链接: 其它
参考链接: heapq — 堆队列算法

代码实验展示:

# 实现多级排序,首先按成绩降序,再按年龄升序,最后按姓名字典序升序
import heapq, random
from tkinter import N
stuTuple = tuple(
    [
        (98, 23, 'mike'),
        (97, 37, 'steve'),
        (92, 18, 'james'),
        (91, 16, 'eric'),
        (99, 12, 'john'),
        (99, 12, 'dave'),
        (99, 14, 'jane'),
        (98, 25, 'jack'),
        (98, 25, 'bob'),
        
    ]
    )
answers = [
    (99, 12, 'dave'),
    (99, 12, 'john'),
    (99, 14, 'jane'),
    (98, 23, 'mike'),
    (98, 25, 'bob'),
    (98, 25, 'jack'),
    (97, 37, 'steve'),
    (92, 18, 'james'),
    (91, 16, 'eric'),
]

def printInfo(ls):
    for item in ls:
        print(item)

ls = list()
for stu in stuTuple:
    ls.append(stu)

def check(res,answers):
    for i in range(9):
        r, a = res[i], answers[i]
        if r[0]!=a[0] or r[1]!=a[1] or r[2]!=a[2]:
            return False
    return True


print("以下为排序前".center(50,'-'))
printInfo(ls)
N = 100
for i in range(N):
    sample = ls[:]
    random.shuffle(sample)
    res = heapq.nsmallest(9,sample,key=lambda x:(-1*x[0],x[1],x[2]))
    if not check(res,answers):
        print("排序结果错误!!!")

print('使用三元组进行排序')
print("以下为排序后".center(50,'-'))
printInfo(res)

控制台结果输出:

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

尝试新的跨平台 PowerShell https://aka.ms/pscore6

加载个人及系统配置文件用了 812 毫秒。
(base) PS C:\Users\chenxuqi\Desktop\测试排序>  & 'D:\Python37\python.exe' 'c:\Users\chenxuqi\.vscode\extensions\ms-python.python-2022.16.1\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher' '1535' '--' 'c:\Users\chenxuqi\Desktop\测试排序\test.py'
----------------------以下为排序前----------------------
(98, 23, 'mike') 
(97, 37, 'steve')
(92, 18, 'james')
(91, 16, 'eric') 
(99, 12, 'john') 
(99, 12, 'dave') 
(99, 14, 'jane')
(98, 25, 'jack')
(98, 25, 'bob')
使用三元组进行排序
----------------------以下为排序后----------------------
(99, 12, 'dave')
(99, 12, 'john')
(99, 14, 'jane')
(98, 23, 'mike')
(98, 25, 'bob')
(98, 25, 'jack')
(97, 37, 'steve')
(92, 18, 'james')
(91, 16, 'eric')
(base) PS C:\Users\chenxuqi\Desktop\测试排序> 

使用cmp函数进行排序,代码实验展示:

# 实现多级排序,首先按成绩降序,再按年龄升序,最后按姓名字典序升序
import heapq, random
from tkinter import N
stuTuple = tuple(
    [
        (98, 23, 'mike'),
        (97, 37, 'steve'),
        (92, 18, 'james'),
        (91, 16, 'eric'),
        (99, 12, 'john'),
        (99, 12, 'dave'),
        (99, 14, 'jane'),
        (98, 25, 'jack'),
        (98, 25, 'bob'),
        
    ]
    )
answers = [
    (99, 12, 'dave'),
    (99, 12, 'john'),
    (99, 14, 'jane'),
    (98, 23, 'mike'),
    (98, 25, 'bob'),
    (98, 25, 'jack'),
    (97, 37, 'steve'),
    (92, 18, 'james'),
    (91, 16, 'eric'),
]

def printInfo(ls):
    for item in ls:
        print(item)

ls = list()
for stu in stuTuple:
    ls.append(stu)

def check(res,answers):
    for i in range(9):
        r, a = res[i], answers[i]
        if r[0]!=a[0] or r[1]!=a[1] or r[2]!=a[2]:
            return False
    return True


print("以下为排序前".center(50,'-'))
printInfo(ls)
##########################################################################

print('使用cmp参数进行排序')
def cmp_to_key(mycmp):
    'Convert a cmp= function into a key= function'
    class K:
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >= 0
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0
    return K

def compareStudent(x, y):  # 返回1表示要交换x和y
    if x[0]>y[0]:
        return -1
    elif x[0]<y[0]:
        return 1
    else:
        if x[1]>y[1]:
            return 1
        elif x[1]<y[1]:
            return -1
        else:
            if x[2]>y[2]:
                return 1
            elif x[2]<y[2]:
                return -1
            else:
                return 0

N = 100
for i in range(N):
    sample = ls[:]
    random.shuffle(sample)
    res = heapq.nsmallest(9,sample,key=cmp_to_key(compareStudent))
    if not check(res,answers):
        print("排序结果错误!!!")

print('使用cmp函数进行排序')
print("以下为排序后".center(50,'-'))
printInfo(res)

控制台结果输出:

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

尝试新的跨平台 PowerShell https://aka.ms/pscore6

加载个人及系统配置文件用了 771 毫秒。
(base) PS C:\Users\chenxuqi\Desktop\测试排序>  & 'D:\Python37\python.exe' 'c:\Users\chenxuqi\.vscode\extensions\ms-python.python-2022.16.1\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher' '1659' '--' 'c:\Users\chenxuqi\Desktop\测试排序\test.py'
----------------------以下为排序前----------------------
(98, 23, 'mike') 
(97, 37, 'steve')
(92, 18, 'james')
(91, 16, 'eric') 
(99, 12, 'john') 
(99, 12, 'dave') 
(99, 14, 'jane')
(98, 25, 'jack')
(98, 25, 'bob')
使用cmp参数进行排序
使用cmp函数进行排序
----------------------以下为排序后----------------------
(99, 12, 'dave')
(99, 12, 'john')
(99, 14, 'jane')
(98, 23, 'mike')
(98, 25, 'bob')
(98, 25, 'jack')
(97, 37, 'steve')
(92, 18, 'james')
(91, 16, 'eric')
(base) PS C:\Users\chenxuqi\Desktop\测试排序> 

使用key=lambda x:(-1*x.grade,x.age,x.name)进行排序,代码实验展示:

# 实现多级排序,首先按成绩降序,再按年龄升序,最后按姓名字典序升序
import heapq, random
stuTuple = tuple(
    [
        (98, 23, 'mike'),
        (97, 37, 'steve'),
        (92, 18, 'james'),
        (91, 16, 'eric'),
        (99, 12, 'john'),
        (99, 12, 'dave'),
        (99, 14, 'jane'),
        (98, 25, 'jack'),
        (98, 25, 'bob'),
    ]
    )

class Student():
    def __init__(self, grade, age, name):
        self.grade = grade
        self.age = age
        self.name = name
    def __repr__(self):
        return "Student(grade={0}, age={1}, name='{2}')"\
            .format(self.grade,self.age,self.name)

answers = [
    Student(99, 12, 'dave'),
    Student(99, 12, 'john'),
    Student(99, 14, 'jane'),
    Student(98, 23, 'mike'),
    Student(98, 25, 'bob'),
    Student(98, 25, 'jack'),
    Student(97, 37, 'steve'),
    Student(92, 18, 'james'),
    Student(91, 16, 'eric'),
]

def printInfo(ls):
    for item in ls:
        print(item)

ls = list()
for stu in stuTuple:
    ls.append(Student(*stu))

def check(res,answers):
    for i in range(9):
        r, a = res[i], answers[i]
        if r.grade!=a.grade or r.age!=a.age or r.name!=a.name:
            return False
    return True

print("以下为排序前".center(50,'-'))
printInfo(ls)
##########################################################################
N = 100
for i in range(N):
    sample = ls[:]
    random.shuffle(sample)
    res = heapq.nsmallest(9,sample,key=lambda x:(-1*x.grade,x.age,x.name))
    if not check(res,answers):
        print("排序结果错误!!!")

print('使用key=lambda x:(-1*x.grade,x.age,x.name)进行排序')
print("以下为排序后".center(50,'-'))
printInfo(res)

控制台结果输出:

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

尝试新的跨平台 PowerShell https://aka.ms/pscore6

加载个人及系统配置文件用了 797 毫秒。
(base) PS C:\Users\chenxuqi\Desktop\测试排序>  & 'D:\Python37\python.exe' 'c:\Users\chenxuqi\.vscode\extensions\ms-python.python-2022.16.1\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher' '1964' '--' 'c:\Users\chenxuqi\Desktop\测试排序\test.py'
----------------------以下为排序前----------------------
Student(grade=98, age=23, name='mike') 
Student(grade=97, age=37, name='steve')
Student(grade=92, age=18, name='james')
Student(grade=91, age=16, name='eric') 
Student(grade=99, age=12, name='john') 
Student(grade=99, age=12, name='dave') 
Student(grade=99, age=14, name='jane')
Student(grade=98, age=25, name='jack')
Student(grade=98, age=25, name='bob')
使用key=lambda x:(-1*x.grade,x.age,x.name)进行排序
----------------------以下为排序后----------------------
Student(grade=99, age=12, name='dave')
Student(grade=99, age=12, name='john')
Student(grade=99, age=14, name='jane')
Student(grade=98, age=23, name='mike')
Student(grade=98, age=25, name='bob')
Student(grade=98, age=25, name='jack')
Student(grade=97, age=37, name='steve')
Student(grade=92, age=18, name='james')
Student(grade=91, age=16, name='eric')
(base) PS C:\Users\chenxuqi\Desktop\测试排序> 

使用__lt__函数进行排序,代码实验展示:

# 实现多级排序,首先按成绩降序,再按年龄升序,最后按姓名字典序升序
import heapq, random
stuTuple = tuple(
    [
        (98, 23, 'mike'),
        (97, 37, 'steve'),
        (92, 18, 'james'),
        (91, 16, 'eric'),
        (99, 12, 'john'),
        (99, 12, 'dave'),
        (99, 14, 'jane'),
        (98, 25, 'jack'),
        (98, 25, 'bob'),
    ]
    )

class Student():
    def __init__(self, grade, age, name):
        self.grade = grade
        self.age = age
        self.name = name
    def __repr__(self):
        return "Student(grade={0}, age={1}, name='{2}')"\
            .format(self.grade,self.age,self.name)

answers = [
    Student(99, 12, 'dave'),
    Student(99, 12, 'john'),
    Student(99, 14, 'jane'),
    Student(98, 23, 'mike'),
    Student(98, 25, 'bob'),
    Student(98, 25, 'jack'),
    Student(97, 37, 'steve'),
    Student(92, 18, 'james'),
    Student(91, 16, 'eric'),
]

def printInfo(ls):
    for item in ls:
        print(item)

ls = list()
for stu in stuTuple:
    ls.append(Student(*stu))

def check(res,answers):
    for i in range(9):
        r, a = res[i], answers[i]
        if r.grade!=a.grade or r.age!=a.age or r.name!=a.name:
            return False
    return True

print("以下为排序前".center(50,'-'))
printInfo(ls)
##########################################################################
print('使用__lt__函数进行排序')
def stu__lessthan(self, y):  # 返回True表示不用交换被比较两者的顺序
    if self.grade != y.grade:
        return self.grade > y.grade
    elif self.age != y.age:
            return self.age < y.age
    else:
            return self.name < y.name
Student.__lt__ = stu__lessthan
##########################################################################
N = 100
for i in range(N):
    sample = ls[:]
    random.shuffle(sample)
    res = heapq.nsmallest(9,sample)
    if not check(res,answers):
        print("排序结果错误!!!")

# print('使用__lt__函数进行排序')
print("以下为排序后".center(50,'-'))
printInfo(res)

控制台结果输出:

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

尝试新的跨平台 PowerShell https://aka.ms/pscore6

加载个人及系统配置文件用了 806 毫秒。
(base) PS C:\Users\chenxuqi\Desktop\测试排序>  & 'D:\Python37\python.exe' 'c:\Users\chenxuqi\.vscode\extensions\ms-python.python-2022.16.1\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher' '2263' '--' 'c:\Users\chenxuqi\Desktop\测试排序\test.py'
----------------------以下为排序前----------------------
Student(grade=98, age=23, name='mike')
Student(grade=97, age=37, name='steve')
Student(grade=92, age=18, name='james')
Student(grade=91, age=16, name='eric')
Student(grade=99, age=12, name='john')
Student(grade=99, age=12, name='dave')
Student(grade=99, age=14, name='jane')
Student(grade=98, age=25, name='jack')
Student(grade=98, age=25, name='bob')
使用__lt__函数进行排序
----------------------以下为排序后----------------------
Student(grade=99, age=12, name='dave')
Student(grade=99, age=12, name='john')
Student(grade=99, age=14, name='jane')
Student(grade=98, age=23, name='mike')
Student(grade=98, age=25, name='bob')
Student(grade=98, age=25, name='jack')
Student(grade=97, age=37, name='steve')
Student(grade=92, age=18, name='james')
Student(grade=91, age=16, name='eric')
(base) PS C:\Users\chenxuqi\Desktop\测试排序> 

使用cmp函数进行排序,代码实验展示:

# 实现多级排序,首先按成绩降序,再按年龄升序,最后按姓名字典序升序
import heapq, random
stuTuple = tuple(
    [
        (98, 23, 'mike'),
        (97, 37, 'steve'),
        (92, 18, 'james'),
        (91, 16, 'eric'),
        (99, 12, 'john'),
        (99, 12, 'dave'),
        (99, 14, 'jane'),
        (98, 25, 'jack'),
        (98, 25, 'bob'),
    ]
    )

class Student():
    def __init__(self, grade, age, name):
        self.grade = grade
        self.age = age
        self.name = name
    def __repr__(self):
        return "Student(grade={0}, age={1}, name='{2}')"\
            .format(self.grade,self.age,self.name)

answers = [
    Student(99, 12, 'dave'),
    Student(99, 12, 'john'),
    Student(99, 14, 'jane'),
    Student(98, 23, 'mike'),
    Student(98, 25, 'bob'),
    Student(98, 25, 'jack'),
    Student(97, 37, 'steve'),
    Student(92, 18, 'james'),
    Student(91, 16, 'eric'),
]

def printInfo(ls):
    for item in ls:
        print(item)

ls = list()
for stu in stuTuple:
    ls.append(Student(*stu))

def check(res,answers):
    for i in range(9):
        r, a = res[i], answers[i]
        if r.grade!=a.grade or r.age!=a.age or r.name!=a.name:
            return False
    return True

print("以下为排序前".center(50,'-'))
printInfo(ls)
##########################################################################
print('使用cmp参数进行排序')
def cmp_to_key(mycmp):
    'Convert a cmp= function into a key= function'
    class K:
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >= 0
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0
    return K

def compareStudent(x, y):  # 返回1表示要交换x和y
    if x.grade>y.grade:
        return -1
    elif x.grade<y.grade:
        return 1
    else:
        if x.age>y.age:
            return 1
        elif x.age<y.age:
            return -1
        else:
            if x.name>y.name:
                return 1
            elif x.name<y.name:
                return -1
            else:
                return 0

##########################################################################
N = 100
for i in range(N):
    sample = ls[:]
    random.shuffle(sample)
    res = heapq.nsmallest(9,sample,key=cmp_to_key(compareStudent))
    if not check(res,answers):
        print("排序结果错误!!!")

# print('使用cmp函数进行排序')
print("以下为排序后".center(50,'-'))
printInfo(res)

控制台结果输出:

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

尝试新的跨平台 PowerShell https://aka.ms/pscore6

加载个人及系统配置文件用了 770 毫秒。
(base) PS C:\Users\chenxuqi\Desktop\测试排序>  & 'D:\Python37\python.exe' 'c:\Users\chenxuqi\.vscode\extensions\ms-python.python-2022.16.1\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher' '2358' '--' 'c:\Users\chenxuqi\Desktop\测试排序\test.py'
----------------------以下为排序前----------------------
Student(grade=98, age=23, name='mike')
Student(grade=97, age=37, name='steve')
Student(grade=92, age=18, name='james')
Student(grade=91, age=16, name='eric')
Student(grade=99, age=12, name='john')
Student(grade=99, age=12, name='dave')
Student(grade=99, age=14, name='jane')
Student(grade=98, age=25, name='jack')
Student(grade=98, age=25, name='bob')
使用cmp参数进行排序
----------------------以下为排序后----------------------
Student(grade=99, age=12, name='dave')
Student(grade=99, age=12, name='john')
Student(grade=99, age=14, name='jane')
Student(grade=98, age=23, name='mike')
Student(grade=98, age=25, name='bob')
Student(grade=98, age=25, name='jack')
Student(grade=97, age=37, name='steve')
Student(grade=92, age=18, name='james')
Student(grade=91, age=16, name='eric')
(base) PS C:\Users\chenxuqi\Desktop\测试排序> 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值