我有一个系统,该系统运行带有ls或dir命令的变体的自定义cli,并返回工作目录中文件和文件夹的列表。
问题是,我可以使用带标志的命令运行命令,该标志返回文件及其时间戳(创建和最后修改的日期),或者返回一个标志返回文件及其文件大小。没有办法在一个cli命令中同时获得两者。
获取时间戳列表时,会进一步复杂化,仅返回一些文件(所有以某些前缀结尾的文件都被忽略了)。这两个列表均未按任何特定顺序排列。
我希望创建一个字典,在一个地方包含每个文件的所有信息。什么是最干净,最有效和最pythonic的方法?
快速数据样本:
dir -time给出506个元素的列表。只有(但不是全部)以.ts结尾的文件带有时间戳。某些文件显示在列表中,但没有时间戳,某些文件(例如以.index结尾的任何文件)根本不显示在列表中。
ch20prefix_20_182.ts 2014-10-22 16:06:20 - 2014-10-22 16:08:51
ch21prefix_21_40.ts 2014-10-14 16:15:42 - 2014-10-14 16:16:51
modinfo_sdk1.23b24L
bs780_ntplatency
ch10prefix_10_237.ts 2014-10-27 11:05:10 - 2014-10-27 11:07:33
ch10prefix_10_277.ts 2014-10-30 14:03:51 - 2014-10-30 14:04:24
video1_6_1.ts
ch11prefix_11_179.ts 2014-10-22 14:53:50 - 2014-10-22 14:56:00`
dir -size给出了967个元素的列表。所有文件都在此处,所有文件都有文件大小。
ch10prefix_10_340.index 159544
ch2prefix_2_705.ts 75958204
0
ch11prefix_11_148.ts 19877616
ch10prefix_10_310.ts 7373924
ch11prefix_11_111.index 17112
ch11prefix_11_278.index 1368
ch2prefix_2_307.ts 6492580
channelConfig.xml.2HD 18144
ch21prefix_21_220.ts 12893604
ch20prefix_20_128.index 1720
乱七八糟有一些押韵和原因,这就是为什么有些文件显示而另一些文件不显示,为什么有些文件带有时间戳而另一些文件没有的原因,但这与该问题无关。
我对如何处理它的想法:
我想要的最终输出是一个字典,每个键作为文件名,并且它的值是另一个字典,其中包含“创建时间”,“时间调制”和“文件大小”的键/值对。这样一来,您可以轻松查找每个文件的所有3条信息。
但是,对我来说困难的部分是找到一种有效的方法来合并每个列表中的数据。首先想到的是循环浏览较大的列表(文件大小),然后对于每个元素,检查它是否在较小的列表中,以及是否存在(并带有时间戳),然后添加数据。但这是非常低效的。尽管我事先知道的较大列表中的某些文件在其他列表中没有时间戳,但是对于所有没有时间戳的文件,我不能说。
列表未排序,但是我想到,如果按文件名排序,则可以采用一种更快的方式从另一个列表中查找每个文件,但是考虑到对列表进行排序的运行时间,值得付出努力。
那么,这里最有效的方法是什么?我主要关心运行时和可读性,但是欢迎在我处理该问题的方式中纳入其他因素。
解决方案
从您的问题很难说出您想要的结果是什么。如果您想要两个列表中的所有文件,即使它们仅出现在一个或另一个列表中,则只需对两个文件进行一次遍历,然后使用collections.defaultdict
from collections import defaultdict
d = defaultdict(dict)
with open('fileA.txt') as f:
for line in f:
name, time = line[:24], line[24:]
name, time = name.strip(), time.strip()
time_created, time_modified = time.split(' - ')
d[name]['time_created'] = time_created
d[name]['time_modified'] = time_modified
with open('fileB.txt') as f:
for line in f:
name, size = line[:24], line[24:]
name, size = name.strip(), size.strip()
d[name]['size'] = size
如果最终结果仅包括两个列表中都出现的文件,则对每个列表进行一次遍历以构造单独的词典。
dA = defaultdict(dict)
dB = defaultdict(dict)
with open('fileA.txt') as f:
for line in f:
name, time = line[:24], line[24:]
name, time = name.strip(), time.strip()
try:
time_created, time_modified = time.split(' - ')
except ValueError:
time_created, time_modified = '', ''
dA[name]['time_created'] = time_created
dA[name]['time_modified'] = time_modified
with open('fileB.txt') as f:
for line in f:
name, size = line[:24], line[24:]
name, size = name.strip(), size.strip()
dB[name]['size'] = size
然后,通过其中一个字典,以创建具有公共键的第三个字典。
d = defaultdict(dict)
for k, v in dA.items():
if k in dB:
d[k] = v
d[k].update(dB[k])
由于这是迄今为止唯一的解决方案,并且@Brian C没有提供解决方案,因此这必须是最有效的。