关于python中的globbing的快速问题。
我有一个文件目录,包括< sync_0001.tif',' sync_0002.tif',...,' sync_2400.tif'。我想获得这些文件的3个子集列表:1个用于前800个文件,第2个800个文件和最后800个文件。唯一的问题是数字之前的0。我无法找出正确的方法来获取这些列表。第三个列表很简单,因为没有0填充这些文件(s3 = glob.glob(' sync_ [1601-2400] .tif')。另外两个比较棘手,因为0前面的数字会有所不同。
我试过这个,但是性格范围不好,'我猜是因为0:
s1 = glob.glob('sync_' + '{[0001-0009], [0010-0099], [0100-0800]}' + '.tif')
s2 = glob.glob('sync_' + '{[0801-0999], [1000-1600]}' + '.tif')
然后我尝试将0移出前面,但得到了一个空列表:
s1 = glob.glob('sync_' + '{000[1-9], 00[10-99], 0[100-800]}' + '.tif')
实现这三个列表的最佳方法是什么?我开始认为我的整个球体都是错误的,所以如果有人能够发出一些很棒的光。谢谢!
答案 0 :(得分:1)
支持glob.glob()
功能的fnmatch
module对于您的任务而言并不够复杂。
只需抓取所有文件名并在排序后对其进行分区:
filenames = sorted(glob.glob('sync_[0-9][0-9][0-9][0-9].tif'))
这是有效的,因为您的数字是填充的,因此可以按字典顺序排序。然后分区:
s1 = [f for f in filenames if 0 < int(f[5:9]) <= 800]
s2 = [f for f in filenames if 800 < int(f[5:9]) <= 1600]
s3 = [f for f in filenames if 1600 < int(f[5:9]) <= 2400]
无论如何,目录I / O将是最慢的。你可以通过循环一次并交换你追加的内容来提高效率:
target = s1 = []
s2 = []
s3 = []
for f in filenames:
num = int(f[5:9])
if num > 800:
target = s2
elif num > 1600:
target = s3
target.append(f)
但对于这样的任务,坚持更简单的列表理解也很好。
答案 1 :(得分:0)
最好的方法是:
sync
由于你已经知道了globbing,其余的是:
import glob
import re
from itertools import izip_longest
# https://docs.python.org/2/library/itertools.html#recipes
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
def sorter(x):
return int(re.search('(\d+)',x).groups()[0])
files = glob.glob('sync*.tif')
sorted_files = sorted(files, key=sorter)
in_batches = list(grouper(sorted_files, 800))
由于模式总是sync_
(编辑后),您可以将上面的代码简化为以下内容:
files = glob.glob('sync_*.tif')
sorted_files = sorted(files, key=lambda x: int(x.split('_')[1]))
in_batches = list(grouper(sorted_files, 800))