Python中的复合排序

1 投票
4 回答
1353 浏览
提问于 2025-04-15 12:32

我有一个Python脚本,它会输出很多数据,下面是一个示例。前面四个字段中的第一个字段总是由两个字母、一个数字、一个斜杠和一个或两个数字组成。

Gi3/2 --.--.--.-- 0024.e89b.c10e Dell Inc.  
Gi5/4 --.--.--.-- 0030.c1cd.f038 HEWLETTPACKARD   
Gi4/3 --.--.--.-- 0020.ac00.6703 INTERFLEX DATENSYSTEME GMBH  
Gi3/7 --.--.--.-- 0009.4392.34f2 Cisco Systems  
Gi6/6 --.--.--.-- 001c.2333.bd5a Dell Inc  
Gi3/16 --.--.--.-- 0009.7c92.7af2 Cisco Systems  
Gi5/12 --.--.--.-- 0020.ac00.3fb0 INTERFLEX DATENSYSTEME GMBH  
Gi4/5 --.--.--.-- 0009.4392.6db2 Cisco Systems  
Gi4/6 --.--.--.-- 000b.cd39.c7c8 Hewlett Packard  
Gi6/4 --.--.--.-- 0021.70d7.8d33 Dell Inc  
Gi6/14 --.--.--.-- 0009.7c91.fa71 Cisco Systems  

我想知道,怎样才能正确地按照第一个字段进行排序,这样这个示例就能变成:

Gi3/2   --.--.--.-- 0024.e89b.c10e  Dell Inc.  
Gi3/7   --.--.--.-- 0009.4392.34f2  Cisco Systems  
Gi3/16  --.--.--.-- 0009.7c92.7af2  Cisco Systems  
Gi4/3   --.--.--.-- 0020.ac00.6703  INTERFLEX DATENSYSTEME GMBH  
Gi4/5   --.--.--.-- 0009.4392.6db2  Cisco Systems  
Gi4/6   --.--.--.-- 000b.cd39.c7c8  Hewlett Packard  
Gi5/4   --.--.--.-- 0030.c1cd.f038  HEWLETT PACKARD  
Gi5/12  --.--.--.-- 0020.ac00.3fb0  INTERFLEX DATENSYSTEME GMBH  
Gi6/14  --.--.--.-- 0009.7c91.fa71  Cisco Systems  
Gi6/4   --.--.--.-- 0021.70d7.8d33  Dell Inc  
Gi6/6   --.--.--.-- 001c.2333.bd5a  Dell Inc  

我之前的尝试都很乱,结果像12这样的数字居然排在5前面!

一如既往,非常感谢你的耐心。

4 个回答

1

你可以为 cmp() 比较函数 定义一个自定义的比较方式,用于 .sort([cmp[, key[, reverse]]]) 的调用:

sort() 方法可以接收一些可选的参数来控制比较的方式。

cmp 是一个自定义的比较函数,它有两个参数(列表中的元素),这个函数应该返回一个负数、零或正数,具体取决于第一个参数是被认为小于、等于还是大于第二个参数:比如可以写成 cmp=lambda x,y: cmp(x.lower(), y.lower())。默认值是 None。

cmp() 函数中,获取数字键并使用 int(field) 来确保进行数字(而不是文本)的比较。

另外,你也可以定义一个 key() 函数(感谢 @ Anurag Uniyal):

key 是一个只有一个参数的函数,用来从每个列表元素中提取一个比较键,比如可以写成 key=str.lower。默认值是 None。

4

要对每一行进行排序,首先要把每一行分成两部分:斜杠(/)前面的部分和斜杠后面的整数部分。这样,每一行就变成了一个像这样的元组:('Gi6', 12)。接下来,你就可以根据这个元组来进行排序。下面是一个例子:

s="""Gi3/2 --.--.--.-- 0024.e89b.c10e Dell Inc.  
Gi5/4 --.--.--.-- 0030.c1cd.f038 HEWLETTPACKARD   
Gi4/3 --.--.--.-- 0020.ac00.6703 INTERFLEX DATENSYSTEME GMBH  
Gi3/7 --.--.--.-- 0009.4392.34f2 Cisco Systems  
Gi6/6 --.--.--.-- 001c.2333.bd5a Dell Inc  
Gi3/16 --.--.--.-- 0009.7c92.7af2 Cisco Systems  
Gi5/12 --.--.--.-- 0020.ac00.3fb0 INTERFLEX DATENSYSTEME GMBH  
Gi4/5 --.--.--.-- 0009.4392.6db2 Cisco Systems  
Gi4/6 --.--.--.-- 000b.cd39.c7c8 Hewlett Packard  
Gi6/4 --.--.--.-- 0021.70d7.8d33 Dell Inc  
Gi6/14 --.--.--.-- 0009.7c91.fa71 Cisco Systems"""

lines = s.split("\n")
def sortKey(l):
    a,b = l.split("/")
    b=int(b[:2].strip())
    return (a,b)

lines.sort(key=sortKey)

for l in lines: print l
5

当然可以!请看下面的内容:

这段代码的意思是,它会检查某个条件是否成立。如果成立,就执行某些操作;如果不成立,就执行其他操作。这种方式在编程中非常常见,叫做“条件判断”。

简单来说,就像我们在生活中做决定一样,比如“如果下雨,我就带伞;如果不下雨,我就不带”。在代码中也是类似的逻辑。

如果你有其他具体的代码或内容需要解释,随时告诉我!

def lineKey (line):
    keyStr, rest = line.split(' ', 1)
    a, b = keyStr.split('/', 1)
    return (a, int(b))

sorted(lines, key=lineKey)

撰写回答