使用填充0s-python对范围进行全局化

时间:2014-04-07 18:29:27

标签: python glob

关于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')

实现这三个列表的最佳方法是什么?我开始认为我的整个球体都是错误的,所以如果有人能够发出一些很棒的光。谢谢!

2 个答案:

答案 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)

最好的方法是:

  1. 全球所有以sync
  2. 开头的文件
  3. 按编号组件
  4. 对列表进行排序
  5. 将其拆分为800块
  6. 由于你已经知道了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))