文件结构如下所示:
folder1
|-----name0000.jpg
|-----name0000.tif
|-----name0001.jpg
|-----name0001.tif
|-----....
|-----....
|-----name2000.jpg
|-----name2000.tif
|-----name2004.tif
|-----....
|-----name2845.tif
|-----other_file.txt
|-----folder2
|-----name0000.jpg
|-----name0000.tif
|-----name0001.jpg
|-----name0001.tif
|-----....
|-----....
|-----name2000.jpg
|-----name2000.tif
|-----other_file2.sh
我怎么能把他们分成这样的小组?在
^{pr2}$总的文件可能有几万,我想要速度。不仅有jpg和tif文件,还可以是其他格式。在
使用^{} 在树上行走。因为这没有给出文件大小,所以需要对每个文件调用^{} 。
接下来,显然要先按扩展名分组,然后按基文件名分组(如果两个文件名之间的唯一区别是某个数字部分被1分开,则两个文件名放在一起),但按文件名对组进行排序。一般来说,对事物进行分组的最简单的方法是对它们进行排序,然后通过^{} 函数按邻接进行分组,之后您总是可以对它们进行排序。
我不知道你实际的分组键应该是什么,因为我想不出任何合理的方法来区分2004和0001-2000,但不能把它和2501分开。同样,我也不确定哪条规则会给你2004-2845,尽管有差距。所以我把这些部分留给你。
所以:
在某些情况下,没有明显的分组键函数,但有一种明显的方法可以判断两个相邻值是否算作同一组的一部分。如果是这样,请将其写成一个老式的
^{pr2}$cmp
函数,如下所示:然后您可以使用排序方法中描述的相同的^{} 函数:
不管怎样做,到目前为止最慢的部分可能是对每个文件调用
stat
。这很可惜,因为os.walk
可能已经有了统计信息,但它永远不会给你。为了优化这一点,您可以直接使用本机api,以尽可能高效地为您提供信息。大多数现代的*nix平台(包括OS X和非古代linux)都有^{} ,这类似于用C实现的增强的{},它可以选择性地为您统计所有文件。旧的*nixe应该至少有}。Windows有^{} ,这更像是一个增强的
nftw
或{os.listdir
-它可以很快地提供每个文件的所有类型的信息,包括大小,但是它不会递归到子目录中,所以您必须手动执行。如果您的比较应该使}和{}或{}和{},那么显然我们需要将每个名称分解为多个部分。中间的一个需要转换成一个数字,这样
^{4}$key0000.jpg
和key0001.jpg
相同,但不是{0009
和0010`将是相邻的(因为它们显然不是字符串)。我想你想要的是这个:*因此,例如,}。使用这个函数,并确保它做你真正想要的。
key0000.jpg
将分解为'key'
,0000
,和{下一步,我们如何使用它作为比较函数?好吧,这几乎是一个正常的词典比较,除了在中间位,如果左位比右位少1,它就等于。所以:
(我们实际上不需要从旧样式的
cmp
函数返回完整的-1/0/1,只需要非0/0/nonzero……但它同样容易,而且可能更易读。)同样,对不同的文件名对调用
keycmp
,以确保它们按您的要求运行。你可能需要一些错误处理。作为标准,
re.match
不能匹配,因为你给了它,比如说,'files.txt'
,你会得到一个AttributeError: 'NoneType' has no attribute 'groups'
。但你应该能弄明白。最后一件事:我不记得} 提供了等效的Python源代码,而且没有那么复杂,所以您只需复制它并将其粘贴到代码中,然后更改它以记住组中最新的值。
groupby
是否对照组中的last值检查每个新值,还是第一个。如果是后者,这个keyfunc
就不起作用了。您可以尝试编写一个有状态的比较器,但是有一个更简单的解决方案:^{最后,如果你觉得迭代器和groupby之类的东西听上去都像希腊语,那么在代码正常工作之前不要试着去做。Generator Tricks for System Programmers会教你希腊语,所有像这样的问题都是e在你的余生里更爱你。(好吧,除非你被迫用另一种没有生成器的语言写作…)
*我确信您不需要
int(number, 10)
,因为Python2.7和3.x不会将int('0123')
解释为八进制的……但是由于我必须查找它以确保它的可读性,使其显式似乎是一个好主意。在@abarnert:它从您的博客中派生出以下代码:分组为相邻值的运行(链接:http://stupidpythonideas.blogspot.com/2014/01/grouping-into-runs-of-adjacent-values.html)
我尝试了Win7中的python2.6.6和centos6.5中的python2.6.6,问题是一样的。因为没有itertools.cmp_到\u键()在这个Python2.6中,我修改了您的代码,希望问题不是来自我的修订。在
大部分的工作是将文件大小转换为人类可读的格式。看看这对你有没有用
请注意,这将处理1KB=1000B而不是1KB=1024B
因此,根据您所在的系统,您可能需要考虑更改它。在
相关问题 更多 >
编程相关推荐