Обратный список в Python на основе условия - PullRequest
0 голосов
/ 29 января 2019

Я хочу отсортировать этот список таким образом, чтобы .log был первым файлом, а файл .gz - в порядке убывания

my_list = [
     '/abc/a.log.1.gz',
     '/abc/a.log',
     '/abc/a.log.30.gz',
     '/abc/a.log.2.gz',
     '/abc/a.log.5.gz',
     '/abc/a.log.3.gz',
     '/abc/a.log.6.gz',
     '/abc/a.log.4.gz',
     '/abc/a.log.12.gz',
     '/abc/a.log.10.gz',
     '/abc/a.log.8.gz',
     '/abc/a.log.14.gz',
     '/abc/a.log.29.gz'
]

Ожидаемый_результат:

my_list = ['/abc/a.log',
        '/abc/a.log.30.gz',
        '/abc/a.log.29.gz',
        '/abc/a.log.29.gz',
        '/abc/a.log.14.gz',
        '/abc/a.log.12.gz',
        '/abc/a.log.10.gz',
        '/abc/a.log.8.gz',
        '/abc/a.log.6.gz',
        '/abc/a.log.5.gz',
        '/abc/a.log.4.gz',
        '/abc/a.log.3.gz',
        '/abc/a.log.2.gz'
        '/abc/a.log.1.gz']

reversed(mylist) также не дает мне желаемого решения.

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Если есть несколько расширений, тогда присвойте ранг в словаре, чтобы иметь большую гибкость

my_list = ['/abc/spa/a.log.1.gz',
 '/abc/spa/a.log',
 '/abc/spa/a.log.30.tar',
 '/abc/spa/a.log.30.gz',
 '/abc/spa/a.log.2.gz']

rank={'log':1,'gz':2,'tar':3}    # 'tar' is optional here
sorted(my_list,key = lambda x : (-rank.get(x.rsplit('.')[-1],0), x),reverse=True)

это даст

['/abc/spa/a.log',
 '/abc/spa/a.log.30.gz',
 '/abc/spa/a.log.2.gz',
 '/abc/spa/a.log.1.gz',
 '/abc/spa/a.log.30.tar']

Для вашего обновленного вопроса

my_list = [
     '/abc/a.log.1.gz',
     '/abc/a.log',
     '/abc/a.log.30.gz',
     '/abc/a.log.2.gz',
     '/abc/a.log.5.gz',
     '/abc/a.log.3.gz',
     '/abc/a.log.6.gz',
     '/abc/a.log.4.gz',
     '/abc/a.log.12.gz',
     '/abc/a.log.10.gz',
     '/abc/a.log.8.gz',
     '/abc/a.log.14.gz',
     '/abc/a.log.29.gz'
]
rank={'log':1,'gz':2,'tar':3}    # 'tar' is optional here
sorted(my_list,key = lambda x : (-rank.get(x.rsplit('.',1)[-1]), int(x.split('.')[-2]) if x.split('.')[-2].isdigit() else 0),reverse=True)

Вывод:

['/abc/a.log',
 '/abc/a.log.30.gz',
 '/abc/a.log.29.gz',
 '/abc/a.log.14.gz',
 '/abc/a.log.12.gz',
 '/abc/a.log.10.gz',
 '/abc/a.log.8.gz',
 '/abc/a.log.6.gz',
 '/abc/a.log.5.gz',
 '/abc/a.log.4.gz',
 '/abc/a.log.3.gz',
 '/abc/a.log.2.gz',
 '/abc/a.log.1.gz']
0 голосов
/ 29 января 2019

Используйте sorted с пользовательской функцией key и reverse=True:

print(sorted(my_list, key=lambda x: (x.endswith('log'), x), reverse=True))
#['/abc/spa/a.log',
# '/abc/spa/a.log.30.gz',
# '/abc/spa/a.log.2.gz',
# '/abc/spa/a.log.1.gz']

На основании обновленного вопроса кажется, что вы пытаетесь отсортировать имена файлов.Я бы рекомендовал использовать os.path для манипулирования этими строками.

Сначала вы можете использовать os.path.splitext, чтобы разделить расширение для сравнения между .log или .gz.Затем снова удалите расширение, чтобы получить номер файла, и преобразуйте его в целое число.

Например:

import os

def get_sort_keys(filepath):
    split_file_path = os.path.splitext(filepath)
    sort_key = (split_file_path[1], *os.path.splitext(split_file_path[0]))
    return (sort_key[0], sort_key[1], int(sort_key[2].strip(".")) if sort_key[2] else 0)

print(sorted(my_list, key=get_sort_keys, reverse=True))
#['/abc/a.log',
# '/abc/a.log.30.gz',
# '/abc/a.log.29.gz',
# '/abc/a.log.14.gz',
# '/abc/a.log.12.gz',
# '/abc/a.log.10.gz',
# '/abc/a.log.8.gz',
# '/abc/a.log.6.gz',
# '/abc/a.log.5.gz',
# '/abc/a.log.4.gz',
# '/abc/a.log.3.gz',
# '/abc/a.log.2.gz',
# '/abc/a.log.1.gz']

В этой версии я не проверяю явно endswith("log")как и раньше, но я полагаюсь на то, что расширение log будет сортироваться после gz лексикографически.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...