Сортировать строки по значению и добавить в список - PullRequest
0 голосов
/ 26 февраля 2019

У меня есть этот список файлов журналов, которые я хочу отсортировать по дате внутри каждого: как вы можете видеть, после LOG_ стоит число, которое является ключом, по которому я хочу отсортировать строку.

Дата в формате yyyymmdd.

LOGS\LOG_20190218_91_02.LOG
LOGS\LOG_20190218_91_05.LOG
LOGS\LOG_20190218_91_00.LOG
LOGS\LOG_20190218_91_22.LOG
LOGS\LOG_20190218_91_10.LOG
LOGS\LOG_20190219_56_22.LOG
LOGS\LOG_20190219_56_24.LOG
LOGS\LOG_20190219_56_25.LOG
LOGS\LOG_20190219_56_26.LOG
LOGS\LOG_20190219_56_03.LOG
LOGS\LOG_20190220_56_22.LOG
LOGS\LOG_20190220_56_07.LOG
LOGS\LOG_20190220_56_13.LOG
LOGS\LOG_20190220_56_17.LOG
LOGS\LOG_20190220_56_21.LOG

Я пробовал разные подходы:

  1. извлекать значение даты, добавлять их в список, выделять их (используя set) и, по каждому,возьмите строку / filepath и добавьте ее в список.Проблема в том, что даты могут различаться по размеру (здесь их всего 3, но их может быть и больше).Таким образом, использование фиксированных списков (возможно) выходит за рамки.

  2. проверьте каждую строку и сверьтесь с предыдущим / следующим, чтобы увидеть, изменилась ли дата.Если изменено, то добавьте все предыдущие пути / строки в список.Все та же проблема, но, возможно, этот подход можно улучшить.

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

Я хотел бы понять, как можно реализовать второе решение.Как правильно хранить файлы / строки с одинаковой датой в собственном списке?

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

list20190218 = [all LOG files with 20190218 value in name]
list20190219 = [all LOG files with 20190219 value in name]
list20190220 = [all LOG files with 20190220 value in name]

... но с переменным количеством списков.

Спасибо

Ответы [ 3 ]

0 голосов
/ 26 февраля 2019

Код ниже.

Создайте именованный кортеж, который будет хранить дату файла.Сортировать список, используя дату в качестве ключа.

from collections import namedtuple, defaultdict
import datetime

FileAttr = namedtuple('FileAttr', 'name date')
files = ['LOGS\LOG_20190218_91_02.LOG',
         'LOGS\LOG_20190218_91_05.LOG',
         'LOGS\LOG_20190218_91_00.LOG',
         'LOGS\LOG_20190218_91_22.LOG',
         'LOGS\LOG_20190218_91_10.LOG',
         'LOGS\LOG_20190219_56_22.LOG',
         'LOGS\LOG_20190219_56_24.LOG',
         'LOGS\LOG_20190219_56_25.LOG',
         'LOGS\LOG_20190219_56_26.LOG',
         'LOGS\LOG_20180219_56_26.LOG',
         'LOGS\LOG_20170219_56_26.LOG',
         'LOGS\LOG_20190219_56_03.LOG',
         'LOGS\LOG_20190220_56_22.LOG',
         'LOGS\LOG_20190220_56_07.LOG',
         'LOGS\LOG_20190220_56_13.LOG',
         'LOGS\LOG_20190220_56_17.LOG',
         'LOGS\LOG_20190220_56_21.LOG']
files_ex = []

for f in files:
    left_idx = f.find('_')
    right_idx = f.find('.')
    date_part = f[left_idx + 1:right_idx][:-6]
    year = int(date_part[:4])
    month = int(date_part[4:6])
    day = int(date_part[6:8])
    dt = datetime.datetime(year, month, day)
    files_ex.append(FileAttr(f, dt))
sorted_files_ex = sorted(files_ex, key=lambda x: x[1])

files_by_date = defaultdict(list)
for file_attr in sorted_files_ex:
    files_by_date[file_attr.date].append(file_attr.name)
for date, files in files_by_date.items():
    print('{} --> {}'.format(date, files))

Вывод:

2019-02-18 00:00:00 --> ['LOGS\\LOG_20190218_91_02.LOG', 'LOGS\\LOG_20190218_91_05.LOG', 'LOGS\\LOG_20190218_91_00.LOG', 'LOGS\\LOG_20190218_91_22.LOG', 'LOGS\\LOG_20190218_91_10.LOG']
2019-02-19 00:00:00 --> ['LOGS\\LOG_20190219_56_22.LOG', 'LOGS\\LOG_20190219_56_24.LOG', 'LOGS\\LOG_20190219_56_25.LOG', 'LOGS\\LOG_20190219_56_26.LOG', 'LOGS\\LOG_20190219_56_03.LOG']
2017-02-19 00:00:00 --> ['LOGS\\LOG_20170219_56_26.LOG']
2018-02-19 00:00:00 --> ['LOGS\\LOG_20180219_56_26.LOG']
2019-02-20 00:00:00 --> ['LOGS\\LOG_20190220_56_22.LOG', 'LOGS\\LOG_20190220_56_07.LOG', 'LOGS\\LOG_20190220_56_13.LOG', 'LOGS\\LOG_20190220_56_17.LOG', 'LOGS\\LOG_20190220_56_21.LOG']
0 голосов
/ 26 февраля 2019

Я также опубликую свое решение.Это более многословно, но, возможно, немного легче понять, чем понимание списка.

import os
import glob
from itertools import groupby
from operator import itemgetter

LOGS = ['LOGS\LOG_20190218_91_02.LOG',
        'LOGS\LOG_20190218_91_05.LOG',
        'LOGS\LOG_20190218_91_00.LOG',
        'LOGS\LOG_20190218_91_22.LOG',
        'LOGS\LOG_20190218_91_10.LOG',
        'LOGS\LOG_20190219_56_22.LOG',
        'LOGS\LOG_20190219_56_24.LOG',
        'LOGS\LOG_20190219_56_25.LOG',
        'LOGS\LOG_20190219_56_26.LOG',
        'LOGS\LOG_20190219_56_03.LOG',
        'LOGS\LOG_20190220_56_22.LOG',
        'LOGS\LOG_20190220_56_07.LOG',
        'LOGS\LOG_20190220_56_13.LOG',
        'LOGS\LOG_20190220_56_17.LOG',
        'LOGS\LOG_20190220_56_21.LOG']

dateList = []

for log in LOGS:
    baseName = os.path.basename(log)
    date = baseName.split('_')[1][:8]
    dateList .append(date)

dateList = (set(dateList))

myDict = {}

for date in dateList:
    for log in LOGS:
        if date in log:
            myDict.setdefault(date, [])

            myDict[date].append(log)

for key, value in myDict.items():
    print(key, value)

Вывод:

20190220 ['LOGS\\LOG_20190220_56_22.LOG', 'LOGS\\LOG_20190220_56_07.LOG', 'LOGS\\LOG_20190220_56_13.LOG', 'LOGS\\LOG_20190220_56_17.LOG', 'LOGS\\LOG_20190220_56_21.LOG']
20190219 ['LOGS\\LOG_20190219_56_22.LOG', 'LOGS\\LOG_20190219_56_24.LOG', 'LOGS\\LOG_20190219_56_25.LOG', 'LOGS\\LOG_20190219_56_26.LOG', 'LOGS\\LOG_20190219_56_03.LOG']
20190218 ['LOGS\\LOG_20190218_91_02.LOG', 'LOGS\\LOG_20190218_91_05.LOG', 'LOGS\\LOG_20190218_91_00.LOG', 'LOGS\\LOG_20190218_91_22.LOG', 'LOGS\\LOG_20190218_91_10.LOG']

Если вы используете print(myDict["20190220"]) ...

['LOGS\\LOG_20190220_56_22.LOG', 'LOGS\\LOG_20190220_56_07.LOG', 'LOGS\\LOG_20190220_56_13.LOG', 'LOGS\\LOG_20190220_56_17.LOG', 'LOGS\\LOG_20190220_56_21.LOG']
0 голосов
/ 26 февраля 2019

Чистым способом сделать это было бы использование словарей.В этом случае ключи будут датами, а значения - соответствующим списком.Чтобы сгруппировать элементы в списке, вы можете использовать itertools.groupby.Вам также нужно указать, что вы хотите сгруппировать список, используя дату, для этого вы можете извлечь подстроку даты из каждой строки в аргументе key:

from itertools import groupby
from operator import itemgetter

d = {k:list(v) for k,v in groupby(data, key=lambda x: itemgetter(1)(x.split('_')))}

Затем просто выполните:

d['20190220']

['LOGS\\LOG_20190220_56_22.LOG\n',
 'LOGS\\LOG_20190220_56_07.LOG\n',
 'LOGS\\LOG_20190220_56_13.LOG\n',
 'LOGS\\LOG_20190220_56_17.LOG\n',
 'LOGS\\LOG_20190220_56_21.LOG']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...