Я пытаюсь взять список из массива и разбить строки, чтобы отсортировать список последовательно по последнему ряду из 6 чисел (например, «042126»). Чтобы сделать это, я бы разделил на '.', Использовал от второго до последнего разбиения строки [-2], а затем отсортировал matchfiles [1] с этой подстрокой.

Файлы должны быть отсортированы следующим образом: erl1.041905, erl1.041907, erl2.041908, erl1.041909, erl2.041910 и т. Д.

Два вопроса: как мне указать неограниченное количество разбиений на строку (в случае более длинных имен, использующих дополнительные '.'? Я использую 4 разбиения, но этот случай может не сработать. Иначе, как бы я просто разделил два раза, работая в обратном направлении?

Что еще более важно, мне возвращается ошибка: объект 'list' не вызывается. Что я делаю неправильно?

Спасибо

matchfiles = [ [1723], ['blue.2017-09-05t15-15-07.erl1.041905.png', 
                        'blue.2017-09-05t15-15-11.erl1.041907.png', 
                        'blue.2017-09-05t15-15-14.erl1.041909.png', 
                        'blue.2017-09-05t14-21-35.erl2.041908.png', 
                        'blue.2017-09-05t14-21-38.erl2.041910.png', 
                        'blue.2017-09-05t14-21-41.erl2.041912.png', 
                        'blue.2017-09-05t14-21-45.erl2.041914.png'], 
                        [09302] ]

matchtry = sorted(matchfiles[1], key = [i.split('.', 4)[-2] for i in 
matchfiles[1]])
2
rNOde 28 Фев 2018 в 01:17

4 ответа

Лучший ответ
  • Аргумент key ожидает функцию, но вы предоставляете ей список, поэтому возникает ошибка list is not callable.

  • Вы должны использовать split('.')[-2], который всегда занимает от второго до последнего элемента.


matchfiles = [ [1723], ['blue.2017-09-05t15-15-07.erl1.041905.png',
                        'blue.2017-09-05t15-15-11.erl1.041907.png',
                        'blue.2017-09-05t15-15-14.erl1.041909.png',
                        'blue.2017-09-05t14-21-35.erl2.041908.png',
                        'blue.2017-09-05t14-21-38.erl2.041910.png',
                        'blue.2017-09-05t14-21-41.erl2.041912.png',
                        'blue.2017-09-05t14-21-45.erl2.041914.png'],
                        [9302] ]

matchtry = sorted(matchfiles[1], key=lambda x: x.rsplit('.')[-2])
print(matchtry)
# ['blue.2017-09-05t15-15-07.erl1.041905.png', 'blue.2017-09-05t15-15-11.erl1.041907.png', 
   'blue.2017-09-05t14-21-35.erl2.041908.png', 'blue.2017-09-05t15-15-14.erl1.041909.png',
   'blue.2017-09-05t14-21-38.erl2.041910.png', 'blue.2017-09-05t14-21-41.erl2.041912.png',
   'blue.2017-09-05t14-21-45.erl2.041914.png']
3
DeepSpace 27 Фев 2018 в 22:24

Параметр key для sorted требует функции. [i.split('.', 4)[-2] for i in matchfiles[1]] - это список, а не функция. Ожидаемая функция действует на один элемент из списка, поэтому вам нужна функция, которая принимает строку и разбивает ее на «.» символ и возвращает второй последний столбец, возможно преобразованный в целое число.

Кроме того, Python не позволяет целым числам начинаться с нуля, поэтому вы должны изменить это [09302] на [9302]. (Начиная с 0 означает, что число будет не десятичным. В Python 2 0427 будет 427 восьмеричным, но в Python 3 восьмеричному числу должно предшествовать 0o. 09302 недопустим в обеих версиях, поскольку восьмеричное число не может содержать 9.)

matchfiles = [ [1723], ['blue.2017-09-05t15-15-07.erl1.041905.png',
                        'blue.2017-09-05t15-15-11.erl1.041907.png',
                        'blue.2017-09-05t15-15-14.erl1.041909.png',
                        'blue.2017-09-05t14-21-35.erl2.041908.png',
                        'blue.2017-09-05t14-21-38.erl2.041910.png',
                        'blue.2017-09-05t14-21-41.erl2.041912.png',
                        'blue.2017-09-05t14-21-45.erl2.041914.png'],
                        [9302] ]

matchtry = sorted(matchfiles[1], key = lambda str: int(str.split('.')[-2]))
1
David Scarlett 27 Фев 2018 в 22:27

Помните, что ключевой аргумент для sorted берет каждый элемент вашей итерации (список в вашем случае) и преобразует его в некоторое значение. Значения каждого элемента после преобразования по ключу определяют порядок сортировки. Поэтому простой способ заставить это работать каждый раз - определить функцию, которая берет один элемент и преобразует его во что-то, что легко сортировать:

def fname_to_value(fname):
    name, ext = os.path.splitext(fname) # remove extension 
    number = name.split('.')[-1]  # Get the last set of stuff after the last '.'
    return number  # no need to convert to int, string compare does what you want

Итак, теперь у вас есть функция, преобразующая имя файла в сортируемое значение. Просто укажите это в качестве ключевого аргумента, и все готово.

matchtry = sorted(matchfiles[1], key = fname_to_value)
for match in matchtry:
    print(match)

Результат:

blue.2017-09-05t15-15-07.erl1.041905.png
blue.2017-09-05t15-15-11.erl1.041907.png
blue.2017-09-05t14-21-35.erl2.041908.png
blue.2017-09-05t15-15-14.erl1.041909.png
blue.2017-09-05t14-21-38.erl2.041910.png
blue.2017-09-05t14-21-41.erl2.041912.png
blue.2017-09-05t14-21-45.erl2.041914.png

Затем вы можете обработать полученный список по мере необходимости.

1
evamicur 27 Фев 2018 в 22:27

Да, проблема в вашем ключе. Вы можете использовать лямбда-выражение: https://en.wikipedia.org/wiki/Anonymous_function#Python

Представьте это как математическую карту. Ключу, используемому для сортировки, нужна функция, поэтому вы определяете лямбда-код:

lambda curr: curr.split('.')[-2]

Это дает каждому текущему объекту в списке имя «curr» и применяет выражение после:. Так что в вашем случае это должно сделать вещь:

matchtry = sorted(matchfiles[1], key=lambda curr: curr.split('.')[-2])
1
toornt 27 Фев 2018 в 22:40