我有这个日志文件列表,我想按每个文件中的日期进行排序:如您所见,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
我尝试了各种方法:
提取日期值,将其添加到列表中,将它们分开(使用set
),然后分别取字符串/文件路径并将其添加到列表中。问题在于日期的大小可能会有所不同(这里只有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]
...但列表数量可变。
谢谢
答案 0 :(得分:2)
一种干净的方法是使用字典。在这种情况下,键将是日期,值将是相应的列表。为了对列表中的元素进行分组,可以使用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']
答案 1 :(得分:2)
下面的代码。
创建一个命名元组,该元组将保留文件日期。使用日期作为键对列表进行排序。
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']
答案 2 :(得分:0)
我还将发布我的解决方案。它更冗长,但可能比列表理解更容易理解。
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']