如何在Python中以非常特定的方式对列表进行排序?

如何在Python中以非常特定的方式对列表进行排序?,python,Python,如何在Python中对列表进行非常显式的排序?我的意思是,项目应该以非常具体的方式排序,而不仅仅是按字母或数字排序。我将收到的输入看起来如下所示: h43948fh4349f84 ./.file.html dsfj940j90f94jf ./abcd.ppt f9j3049fj349f0j ./abcd_FF_000000001.jpg f0f9049jf043930 ./abcd_FF_000000002.jpg j909jdsa094jf49 ./abcd_FF_000000003.jpg

如何在Python中对列表进行非常显式的排序?我的意思是,项目应该以非常具体的方式排序,而不仅仅是按字母或数字排序。我将收到的输入看起来如下所示:

h43948fh4349f84 ./.file.html
dsfj940j90f94jf ./abcd.ppt
f9j3049fj349f0j ./abcd_FF_000000001.jpg
f0f9049jf043930 ./abcd_FF_000000002.jpg
j909jdsa094jf49 ./abcd_FF_000000003.jpg
jf4398fj9348fjj ./abcd_FFinit.jpg
9834jf9483fj43f ./abcd_MM_000000001.jpg
fj09jw93fj930fj ./abcd_MM_000000002.jpg
fjdsjfd89s8hs9h ./abcd_MM_000000003.jpg
vyr89r8y898r839 ./abcd_MMinit.jpg
该列表应按以下顺序排序:

  • html文件优先
  • ppt文件秒
  • 菲尼特档案第三
  • MMinit文件第四
  • 其余编号文件的顺序为FF/MM
  • 此示例的输出如下所示:

    h43948fh4349f84 ./.file.html
    dsfj940j90f94jf ./abcd.ppt
    jf4398fj9348fjj ./abcd_FFinit.jpg
    vyr89r8y898r839 ./abcd_MMinit.jpg
    f9j3049fj349f0j ./abcd_FF_000000001.jpg
    9834jf9483fj43f ./abcd_MM_000000001.jpg
    f0f9049jf043930 ./abcd_FF_000000002.jpg
    fj09jw93fj930fj ./abcd_MM_000000002.jpg
    j909jdsa094jf49 ./abcd_FF_000000003.jpg
    fjdsjfd89s8hs9h ./abcd_MM_000000003.jpg
    

    您可以使用
    参数来
    排序()。
    list
    类的此方法接受列表的一个元素并返回一个值,该值可与其他返回值进行比较,以确定排序顺序。一种可能是按照您在问题中的描述为每个条件指定一个数字。

    您可以使用
    参数来
    排序()。
    list
    类的此方法接受列表的一个元素并返回一个值,该值可与其他返回值进行比较,以确定排序顺序。一种可能是按照您在问题中描述的方式为每个标准指定一个数字。

    您需要定义一个
    函数来指导排序。当比较值以查看结果时,将使用键函数的结果,而不是直接使用值

    键函数可以返回任何内容,但这里的元组会很有帮助。元组按字典顺序进行比较,这意味着只有它们的第一个元素被比较,除非它们相等,然后使用第二个元素。如果这些元素也相等,则比较更多的元素,直到没有更多的元素或确定了顺序

    对于您的情况,您可以在第一个位置生成一个数字,以对“特殊”条目进行排序,然后在第二个位置返回数字,在最后一个位置返回
    FF
    MM
    字符串:

    def key(filename):
        if filename.endswith('.html'):
            return (0,)  # html first
        if filename.endswith('.ppt'):
            return (1,)  # ppt second
        if filename.endswith('FFinit.jpg'):
            return (2,)  # FFinit third
        if filename.endswith('MMinit.jpg'):
            return (3,)  # MMinit forth
        # take last two parts between _ characters, ignoring the extension
        _, FFMM, number = filename.rpartition('.')[0].rsplit('_', 2)
        # rest is sorted on the number (compared here lexicographically) and FF/MM
        return (4, number, FFMM)
    
    请注意,元组的长度甚至不必相等

    这将产生预期的输出:

    >>> from pprint import pprint
    >>> lines = '''\
    ... h43948fh4349f84 ./.file.html
    ... dsfj940j90f94jf ./abcd.ppt
    ... f9j3049fj349f0j ./abcd_FF_000000001.jpg
    ... f0f9049jf043930 ./abcd_FF_000000002.jpg
    ... j909jdsa094jf49 ./abcd_FF_000000003.jpg
    ... jf4398fj9348fjj ./abcd_FFinit.jpg
    ... 9834jf9483fj43f ./abcd_MM_000000001.jpg
    ... fj09jw93fj930fj ./abcd_MM_000000002.jpg
    ... fjdsjfd89s8hs9h ./abcd_MM_000000003.jpg
    ... vyr89r8y898r839 ./abcd_MMinit.jpg
    ... '''.splitlines()
    >>> pprint(sorted(lines, key=key))
    ['h43948fh4349f84 ./.file.html',
     'dsfj940j90f94jf ./abcd.ppt',
     'jf4398fj9348fjj ./abcd_FFinit.jpg',
     'vyr89r8y898r839 ./abcd_MMinit.jpg',
     'f9j3049fj349f0j ./abcd_FF_000000001.jpg',
     '9834jf9483fj43f ./abcd_MM_000000001.jpg',
     'f0f9049jf043930 ./abcd_FF_000000002.jpg',
     'fj09jw93fj930fj ./abcd_MM_000000002.jpg',
     'j909jdsa094jf49 ./abcd_FF_000000003.jpg',
     'fjdsjfd89s8hs9h ./abcd_MM_000000003.jpg']
    

    您需要定义一个
    函数来指导排序。当比较值以查看结果时,将使用键函数的结果,而不是直接使用值

    键函数可以返回任何内容,但这里的元组会很有帮助。元组按字典顺序进行比较,这意味着只有它们的第一个元素被比较,除非它们相等,然后使用第二个元素。如果这些元素也相等,则比较更多的元素,直到没有更多的元素或确定了顺序

    对于您的情况,您可以在第一个位置生成一个数字,以对“特殊”条目进行排序,然后在第二个位置返回数字,在最后一个位置返回
    FF
    MM
    字符串:

    def key(filename):
        if filename.endswith('.html'):
            return (0,)  # html first
        if filename.endswith('.ppt'):
            return (1,)  # ppt second
        if filename.endswith('FFinit.jpg'):
            return (2,)  # FFinit third
        if filename.endswith('MMinit.jpg'):
            return (3,)  # MMinit forth
        # take last two parts between _ characters, ignoring the extension
        _, FFMM, number = filename.rpartition('.')[0].rsplit('_', 2)
        # rest is sorted on the number (compared here lexicographically) and FF/MM
        return (4, number, FFMM)
    
    请注意,元组的长度甚至不必相等

    这将产生预期的输出:

    >>> from pprint import pprint
    >>> lines = '''\
    ... h43948fh4349f84 ./.file.html
    ... dsfj940j90f94jf ./abcd.ppt
    ... f9j3049fj349f0j ./abcd_FF_000000001.jpg
    ... f0f9049jf043930 ./abcd_FF_000000002.jpg
    ... j909jdsa094jf49 ./abcd_FF_000000003.jpg
    ... jf4398fj9348fjj ./abcd_FFinit.jpg
    ... 9834jf9483fj43f ./abcd_MM_000000001.jpg
    ... fj09jw93fj930fj ./abcd_MM_000000002.jpg
    ... fjdsjfd89s8hs9h ./abcd_MM_000000003.jpg
    ... vyr89r8y898r839 ./abcd_MMinit.jpg
    ... '''.splitlines()
    >>> pprint(sorted(lines, key=key))
    ['h43948fh4349f84 ./.file.html',
     'dsfj940j90f94jf ./abcd.ppt',
     'jf4398fj9348fjj ./abcd_FFinit.jpg',
     'vyr89r8y898r839 ./abcd_MMinit.jpg',
     'f9j3049fj349f0j ./abcd_FF_000000001.jpg',
     '9834jf9483fj43f ./abcd_MM_000000001.jpg',
     'f0f9049jf043930 ./abcd_FF_000000002.jpg',
     'fj09jw93fj930fj ./abcd_MM_000000002.jpg',
     'j909jdsa094jf49 ./abcd_FF_000000003.jpg',
     'fjdsjfd89s8hs9h ./abcd_MM_000000003.jpg']
    

    使用
    排序
    和自定义
    功能

    strings = ['h43948fh4349f84 ./.file.html',
    'dsfj940j90f94jf ./abcd.ppt',
    'f9j3049fj349f0j ./abcd_FF_000000001.jpg',
    'f0f9049jf043930 ./abcd_FF_000000002.jpg',
    'j909jdsa094jf49 ./abcd_FF_000000003.jpg',
    'jf4398fj9348fjj ./abcd_FFinit.jpg',
    '9834jf9483fj43f ./abcd_MM_000000001.jpg',
    'fj09jw93fj930fj ./abcd_MM_000000002.jpg',
    'fjdsjfd89s8hs9h ./abcd_MM_000000003.jpg',
    'vyr89r8y898r839 ./abcd_MMinit.jpg']
    
    def key(string):    
        if string.endswith('html'):
            return 0,
        elif string.endswith('ppt'):
            return 1,
        elif string.endswith('FFinit.jpg'):
            return 2,
        elif string.endswith('MMinit.jpg'):
            return 3,
        elif string[-16:-14] == 'FF':
            return 4, int(string[-13:-4]), 0
        elif string[-16:-14] == 'MM':
            return 4, int(string[-13:-4]), 1
    
    result = sorted(strings, key=key)
    
    for string in result:
        print(string)
    
    Out:
    h43948fh4349f84 ./.file.html
    dsfj940j90f94jf ./abcd.ppt
    jf4398fj9348fjj ./abcd_FFinit.jpg
    vyr89r8y898r839 ./abcd_MMinit.jpg
    f9j3049fj349f0j ./abcd_FF_000000001.jpg
    9834jf9483fj43f ./abcd_MM_000000001.jpg
    f0f9049jf043930 ./abcd_FF_000000002.jpg
    fj09jw93fj930fj ./abcd_MM_000000002.jpg
    j909jdsa094jf49 ./abcd_FF_000000003.jpg
    fjdsjfd89s8hs9h ./abcd_MM_000000003.jpg
    

    使用
    排序
    和自定义
    功能

    strings = ['h43948fh4349f84 ./.file.html',
    'dsfj940j90f94jf ./abcd.ppt',
    'f9j3049fj349f0j ./abcd_FF_000000001.jpg',
    'f0f9049jf043930 ./abcd_FF_000000002.jpg',
    'j909jdsa094jf49 ./abcd_FF_000000003.jpg',
    'jf4398fj9348fjj ./abcd_FFinit.jpg',
    '9834jf9483fj43f ./abcd_MM_000000001.jpg',
    'fj09jw93fj930fj ./abcd_MM_000000002.jpg',
    'fjdsjfd89s8hs9h ./abcd_MM_000000003.jpg',
    'vyr89r8y898r839 ./abcd_MMinit.jpg']
    
    def key(string):    
        if string.endswith('html'):
            return 0,
        elif string.endswith('ppt'):
            return 1,
        elif string.endswith('FFinit.jpg'):
            return 2,
        elif string.endswith('MMinit.jpg'):
            return 3,
        elif string[-16:-14] == 'FF':
            return 4, int(string[-13:-4]), 0
        elif string[-16:-14] == 'MM':
            return 4, int(string[-13:-4]), 1
    
    result = sorted(strings, key=key)
    
    for string in result:
        print(string)
    
    Out:
    h43948fh4349f84 ./.file.html
    dsfj940j90f94jf ./abcd.ppt
    jf4398fj9348fjj ./abcd_FFinit.jpg
    vyr89r8y898r839 ./abcd_MMinit.jpg
    f9j3049fj349f0j ./abcd_FF_000000001.jpg
    9834jf9483fj43f ./abcd_MM_000000001.jpg
    f0f9049jf043930 ./abcd_FF_000000002.jpg
    fj09jw93fj930fj ./abcd_MM_000000002.jpg
    j909jdsa094jf49 ./abcd_FF_000000003.jpg
    fjdsjfd89s8hs9h ./abcd_MM_000000003.jpg
    

    我假设最后一个订购点只是查看了文件扩展名之前的数字(例如000001)


    我假设最后一个订购点只是查看了文件扩展名之前的数字(例如000001)


    当然,只需设计一个键就可以生成这样排序的对象。当然,只需设计一个键就可以生成这样排序的对象。
    sort()
    不是一个函数。这是一个关于
    列表
    对象的方法
    sorted()
    是函数的名称(它接受任何iterable)。@MartijnPieters来自Java世界,我在心里交替使用“function”和“method”。@code学徒即使在Python世界中你也没有错,一般来说OOP术语方法仍然只是特殊类型的函数。
    sort()
    不是一个函数。这是一个关于
    列表
    对象的方法
    sorted()
    是函数的名称(它接受任何iterable)。@MartijnPieters来自Java世界,我在心里交替使用“function”和“method”。@code学徒即使在Python世界你也没有错,一般来说OOP术语方法仍然只是特殊类型的函数。这产生了错误的顺序,所有th
    FF_0*.jpg
    文件位于
    MM_0*.jpg
    文件之前。这些文件应该先按数字排序,然后按
    FF
    vs
    MM
    排序。谢谢,我是根据它们的描述而不是它们的示例输出来排序的。现在应该修复。这会产生错误的顺序,所有th
    FF_0*.jpg
    文件都在
    MM_0*.jpg
    文件之前。这些文件应该先按数字排序,然后按
    FF
    vs
    MM
    排序。谢谢,我是根据它们的描述而不是它们的示例输出来排序的。现在应该修好了。