繁体   English   中英

如何使用关键函数在python中按填充字符串属性排序

[英]How to sort by padded string attribute in python using key functions

假设l是具有String属性x的c类对象的列表。 l应该根据以下标准进行排序:对于任何两个项目:在最后一个斜杠字符处分割x,取后缀,在两个字符的开头添加零填充以使它们的长度相等,并按字母顺序进行比较。 我读到应该使用key函数对python进行排序。 但是,我无法找到以这种方式达到所需排序标准的任何方法。 如果关键功能不是实现所需排序的正确方法,那么我很高兴使用“正确”方法的解决方案。

使用键功能很难做到。 使用自定义比较功能会更容易。 Python 2支持sort自定义比较功能,但Python 3不支持。 但是,使用键函数进行排序比使用自定义比较函数高效得多:键函数仅对列表中的每个项目调用一次,而每次进行比较时都必须调用自定义比较函数。

解决此问题的“关键”是要认识到,只要要比较的两个字符串的长度相等,就可以在每个字符串中添加多少个零都无关紧要。 因此,我们只需要确定数据中最长字符串的长度,并将所有字符串填充到该长度即可。

要确定该长度,我们可以使用一个相对简单的生成器表达式,该表达式使用rsplit来获取最后斜杠之后的字符串部分的长度,并将这些长度传递给内置的max函数。 然后,我们可以在键函数中使用该最大长度。

以下代码适用于Python 2,但如果您在show函数中修复了print语句,它将在Python 3 show运行。

#!/usr/bin/env python

data = [
    'a/bc/this',
    'a/bc/is',
    'a/bc/a',
    'a/bc/short',
    'a/bc/test',
    'a/bc/123',
    'a/bc/24',
    'a/bc/5',
]

#Simple sequence printer
def show(seq):
    for row in seq:
        print row
    print

#Get maximum length of the string after the last slash in each data string
maxlen = max(len(s.rsplit('/', 1)[1]) for s in data)

#Key function that pads the string after the last slash
key = lambda s: s.rsplit('/', 1)[1].rjust(maxlen, '0')

#Test the key function
show([(s, key(s)) for s in data])

new_data = sorted(data, key=key)
show(new_data)

产量

('a/bc/this', '0this')
('a/bc/is', '000is')
('a/bc/a', '0000a')
('a/bc/short', 'short')
('a/bc/test', '0test')
('a/bc/123', '00123')
('a/bc/24', '00024')
('a/bc/5', '00005')

a/bc/5
a/bc/a
a/bc/24
a/bc/is
a/bc/123
a/bc/test
a/bc/this
a/bc/short

我不知道Timsort如何使用键函数进行排序的确切细节,但它等效于:

  1. 将项目列表变成(键,项目)元组列表。
  2. 对元组列表进行排序,仅对键进行排序,而忽略该项。
  3. 通过从已排序列表中的元组中删除项目来重建新的项目列表。

这只是一个粗略的指南,因为Timsort用C编写。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM