python多级排序(sorted())

本文探讨Python中sorted函数的使用,特别是在处理多级排序问题上的应用。通过示例展示了如何利用sorted进行字符统计、ASCII码排序,以及对字典进行多级排序的方法,并提到了Python的operator模块在多级排序中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      python里有两个排序函数。sort()  是list专用的,比如list1.sort()   它本身是就地修改,无返回值。

另一个排序函数就是sorted,返回新的排序后的值。这是所有数据类型都可以用的,包括字符串等。

本文主要讨论sorted函数

参考文章:

sort、sorted排序技巧(多级排序)   https://www.jianshu.com/p/d1a26a9a2496

 先来一道题:

牛客网上的华为机试题

题目描述

如果统计的个数相同,则按照ASCII码由小到大排序输出 。如果有其他字符,则对这些字符不用进行统计。

实现以下接口:
输入一个字符串,对字符中的各个英文字符,数字,空格进行统计(可反复调用)
按照统计个数由多到少输出统计结果,如果统计的个数相同,则按照ASII码由小到大排序输出
清空目前的统计结果,重新统计
调用者会保证:
输入的字符串以‘\0’结尾。

输入描述:

输入一串字符。

输出描述:

对字符中的
各个英文字符(大小写分开统计),数字,空格进行统计,并按照统计个数由多到少输出,如果统计的个数相同,则按照ASII码由小到大排序输出 。如果有其他字符,则对这些字符不用进行统计。

示例1

输入

aadddccddc

输出

dca

我开始对sorted的使用不大熟悉,就写了这样的代码,虽然直观,但是哈哈:

while True:
    try:
        x=input()
        dic={}
        dic[' ']=0
        #print(dic.keys())
        for i in range(len(x)):
            if x[i]==' ':
                dic[' ']+=1
            elif (ord(x[i])<=ord('9') and ord(x[i])>=ord(('0'))) or (ord('a')<=ord(x[i]) and ord(x[i])<ord('z')) or (ord('A')<=ord(x[i]) and ord(x[i])<ord('Z')):
                if x[i] not in dic.keys():
                    dic[x[i]]=1
                else:
                    dic[x[i]]+=1
            else:
                pass
        keyr = sorted(dic.items(), key=lambda x: x[1], reverse=True)
        for i in range(1,len(keyr)):
            if keyr[i][1]==keyr[i-1][1]:
                if ord(keyr[i][0])<ord(keyr[i-1][0]):
                    temp = keyr[i-1]
                    keyr[i-1]=keyr[i]
                    keyr[i]=temp
        str1=''
        for i in range(len(keyr)):
            str1=str1+str(keyr[i][0])
        print(str1)
    except:
        break

我用了一个sorted,后面针对相同个数的按照ASCII排序,我就用的 if 判断了。

(注意:sorted之后,就变成了列表list类型了,对于字典的话,列表内部是元组形式了(元组不能更改))

大神的做法呢?

import sys
while True:
    s = sys.stdin.readline().strip()
    if s:
        dic = {}
        for ch in s:
            if ch not in dic:
                dic[ch] = 0
            dic[ch] += 1
        dct = sorted(sorted(dic.items(), key=lambda x: x[0]), key=lambda y: y[1], reverse=True)
        ct = ''.join([k for (k, v) in dct])
        print(ct)
    else:
        break

比较惊喜的就是sorted的两次使用。测试输入:aabbbccc

第一次就是按照ASCII排序(用dict1.items(),得到包含键,值的元组,由于迭代对象是元组,返回值自然是元组组成的列表这里对排序的规则进行了定义,x指元组,x[1]是值,x[0]是键)

第二次就是按照数目排序。sorted()为了保持稳定性,当排序时,key相同的时候,不改变原来的位置。

反过来写,也是可以的。

       dat = sorted(dic.items(), key=lambda x: x[1], reverse=True)
#第一次是按照数量降序排列
       dct= sorted(dat,key=lambda x:x[0])
#第二次按照ASCII码升序,字母数字的排序,默认是按照ASCII升序

sort_result=sorted(iterable,key=lamda: 排序标准,reverse=False)

等号左边是返回值,第一个参数是排序对象,第二个是key,排序标准,第三个默认升序)。如下:

 >>> 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_objects = [  
        Student('john', 'A', 15),  
        Student('jane', 'B', 12),  
        Student('dave', 'B', 10),  
        ]  
>>> sorted(student_objects, key=lambda student: student.age)   # sort by age  
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

多级排序,python3已经有专用的模块了

多级排序(内置模块)opereator

【文档:https://docs.python.org/zh-cn/3.7/howto/sorting.html】

import operator

a = [(1,2,3),(3,4,5),(0,1,2)]

a.sort(key = operator.itemgetter(1,2)) #根据元组第1和第2位元素排序

print a-->[(0,1,2),(1,2,3),(3,4,5)]

operator模块有itemgetter,attrgetter,从2.6开始还增加了methodcaller方法。使用这些方法,上面的操作将变得更加简洁和快速:

>>> from operator import itemgetter, attrgetter  
>>> sorted(student_tuples, key=itemgetter(2))  
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]  
>>> sorted(student_objects, key=attrgetter('age'))  
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]  

operator模块还允许多级的排序,例如,先以grade,然后再以age来排序:

>>> sorted(student_tuples, key=itemgetter(1,2))  
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]  
>>> sorted(student_objects, key=attrgetter('grade', 'age'))  
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]  

可是这样的模块,针对我们这道题该怎么实现呢?好像还是两次sorted才能解决呢。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值