Я пытаюсь отсортировать дату внутри своего списка, но даты идут после строкового элемента [EQUIP-X]. Сначала с помощью регулярных выражений, взять единственную дату и попытаться отсортировать. Это не работает!

Я думал разделить строку [EQUIP-X] и Date.

files = [filename for root, dirs, files in os.walk(path) for filename in files for date in dateList if filename.endswith(date+".log")]
for item in files:
 reg = re.search(r"(.+]).(\d{2}.\d{2}.\d{4})",item)
 equip = reg.group(1)
 data = reg.group(2)
 namefile = data+'.'+equip 
 print item
  • группа (1) - [EQUIP-X]
  • группа (2) - Дата

Пример строки:

[EQUIP-4].02.05.2019.log
[EQUIP-2].01.05.2019.log
[EQUIP-1].30.04.2019.log
[EQUIP-3].29.04.2019.log
[EQUIP-1].01.05.2019.log
[EQUIP-5].30.04.2019.log
[EQUIP-1].29.04.2019.log
[EQUIP-5].30.04.2019.log
[EQUIP-3].30.04.2019.log
[EQUIP-1].29.04.2019.log
[EQUIP-2].02.05.2019.log

Следуя этому руководству, не существует атрибута 'sort' для объекта 'str', как только Я не манипулирую «датой», а «str». Как лучше это сделать? Идея заключалась в том, чтобы разделить и обработать дату, а затем объединить все

2
ThiagoL 2 Май 2019 в 22:02

6 ответов

Лучший ответ

Вы можете просто отсортировать по концу строки минус последние 4 символа (расширение файла), проанализированные как дата. Поскольку формат даты дополняется нулями, он всегда должен иметь длину 10 символов, следовательно, слияние строк начинается с -14 (10 для даты + 4 для расширения)

from datetime import datetime

files = ['[EQUIP-4].02.05.2019.log',
'[EQUIP-2].01.05.2019.log',
'[EQUIP-1].30.04.2019.log',
'[EQUIP-3].29.04.2019.log',
'[EQUIP-1].01.05.2019.log',
'[EQUIP-5].30.04.2019.log',
'[EQUIP-1].29.04.2019.log',
'[EQUIP-5].30.04.2019.log',
'[EQUIP-3].30.04.2019.log',
'[EQUIP-1].29.04.2019.log',
'[EQUIP-2].02.05.2019.log']

files.sort(key=lambda x: datetime.strptime(x[-14:-4], '%d.%m.%Y'))
print(files)
['[EQUIP-3].29.04.2019.log',
'[EQUIP-1].29.04.2019.log',
'[EQUIP-1].29.04.2019.log',
'[EQUIP-1].30.04.2019.log',
'[EQUIP-5].30.04.2019.log',
'[EQUIP-5].30.04.2019.log',
'[EQUIP-3].30.04.2019.log',
'[EQUIP-2].01.05.2019.log',
'[EQUIP-1].01.05.2019.log',
'[EQUIP-4].02.05.2019.log',
'[EQUIP-2].02.05.2019.log']
2
Sayse 2 Май 2019 в 19:18

Комбинируя предложения @ ddg и @ Sayse, вы можете попробовать:

import re
from datetime import datetime

files = ["[EQUIP-4].02.05.2019.log", ...]

files.sort(key = lambda item: datetime.strptime(re.search(r"(?=.)(\d{2}.\d{2}.\d{4})(?=.)", item).group(0), '%d.%m.%Y'), reverse=False)

Или в более читабельном виде:

def getSortValue(item):
  reg = re.search(r"(?=.)(\d{2}.\d{2}.\d{4})(?=.)", item)
  data = reg.group(0)
  return datetime.strptime(data, '%d.%m.%Y')

files.sort(key = getSortValue, reverse = False)

Выход:

print('\n'.join(files))

[EQUIP-3].29.04.2019.log
[EQUIP-1].29.04.2019.log
[EQUIP-1].29.04.2019.log
[EQUIP-1].30.04.2019.log
[EQUIP-5].30.04.2019.log
[EQUIP-5].30.04.2019.log
[EQUIP-3].30.04.2019.log
[EQUIP-2].01.05.2019.log
[EQUIP-1].01.05.2019.log
[EQUIP-4].02.05.2019.log
[EQUIP-2].02.05.2019.log
1
Joseph Kvitova 2 Май 2019 в 19:45

Вы можете преобразовать свой список в фрейм данных panda, а затем выполнить соответствующую сортировку. Сортировка по году, месяцу и дню, а затем преобразование индекса в список. Затем отобразите отсортированные значения по индексу (iloc).

import pandas as pd
df = pd.DataFrame([('[EQUIP-4].02.05.2019.log')
,('[EQUIP-2].01.05.2019.log')
,('[EQUIP-1].30.04.2019.log')
,('[EQUIP-3].29.04.2019.log')
,('[EQUIP-1].01.05.2019.log')
,('[EQUIP-5].30.04.2019.log')
,('[EQUIP-1].29.04.2019.log')
,('[EQUIP-5].30.04.2019.log')
,('[EQUIP-3].30.04.2019.log')
,('[EQUIP-1].29.04.2019.log')
,('[EQUIP-2].02.05.2019.log')], columns = ['file'])

df.iloc[df['file'] \
      .map(lambda x: pd.to_datetime(x[-14:-4])) \
      .sort_values() \
      .index \
      .tolist()]

Результат:

                 file
1   [EQUIP-2].01.05.2019.log
4   [EQUIP-1].01.05.2019.log
0   [EQUIP-4].02.05.2019.log
10  [EQUIP-2].02.05.2019.log
3   [EQUIP-3].29.04.2019.log
6   [EQUIP-1].29.04.2019.log
9   [EQUIP-1].29.04.2019.log
2   [EQUIP-1].30.04.2019.log
5   [EQUIP-5].30.04.2019.log
7   [EQUIP-5].30.04.2019.log
8   [EQUIP-3].30.04.2019.log
1
âńōŋŷXmoůŜ 2 Май 2019 в 19:35

Функция python sort имеет параметр key, который позволяет изменить элемент перед его сортировкой.

В этом примере извлекается число из конца строки и сортируется по нему.

a = ['hello 123', 'pumpkin 542', 'muffin 342']

def get_important_part(string):
    return int(string.split()[1])

print(sorted(a, key=get_important_part))

Возвращается

['hello 123', 'muffin 342', 'pumpkin 542']

1
ddg 2 Май 2019 в 19:13

Вы можете сортировать имена файлов с помощью встроенного list sort(), например:

from datetime import datetime
import os  # Even though not used in example code.
from pprint import pprint
import re

#files = [filename for root, dirs, files in os.walk(path) for filename in files for date in dateList if filename.endswith(date+".log")]
files = [
    '[EQUIP-4].02.05.2019.log',
    '[EQUIP-2].01.05.2019.log',
    '[EQUIP-1].30.04.2019.log',
    '[EQUIP-3].29.04.2019.log',
    '[EQUIP-1].01.05.2019.log',
    '[EQUIP-5].30.04.2019.log',
    '[EQUIP-1].29.04.2019.log',
    '[EQUIP-5].30.04.2019.log',
    '[EQUIP-3].30.04.2019.log',
    '[EQUIP-1].29.04.2019.log',
    '[EQUIP-2].02.05.2019.log',
]

def get_date(filename):
    match = re.search(r".+].(\d{2}.\d{2}.\d{4})",filename)
    date_str = match.group(1)
    return datetime.strptime(date_str, '%d.%m.%Y')

files.sort(key=get_date)

pprint(files)

Выход:

['[EQUIP-3].29.04.2019.log',
 '[EQUIP-1].29.04.2019.log',
 '[EQUIP-1].29.04.2019.log',
 '[EQUIP-1].30.04.2019.log',
 '[EQUIP-5].30.04.2019.log',
 '[EQUIP-5].30.04.2019.log',
 '[EQUIP-3].30.04.2019.log',
 '[EQUIP-2].01.05.2019.log',
 '[EQUIP-1].01.05.2019.log',
 '[EQUIP-4].02.05.2019.log',
 '[EQUIP-2].02.05.2019.log']
0
martineau 2 Май 2019 в 19:35

Почему бы не работать с strptime и strftime?

dates = ['02.05.2019', '20.05.2019', '11.05.2019', '30.05.2019', '08.05.2019', '09.05.2019']
dates_obj = [datetime.strptime(x,'%d.%m.%Y') for x in dates]
dates_sorted = sorted(dates_obj)
dates_sorted = [x.strftime('%d.%m.%Y') for x in dates_sorted]
print (dates_sorted)

['02/05/2019', '08/05/2019', '09/05/2019', '11/05/2019', '20/05/2019', '30/05/2019']
1
Murilo Sitonio 2 Май 2019 в 19:26