2014-04-07 4 views
0

파이썬에서 globbing과 관련된 빠른 질문.패딩이있는 범위를 globbing하기 0- 파이썬

'sync_0001.tif', 'sync_0002.tif', ..., 'sync_2400.tif'파일의 디렉토리가 있습니다. 그 파일들에 대한 3 개의 서브셋 목록을 얻고 싶습니다 : 첫 번째 800 파일, 두 번째 800 파일, 마지막 800 파일. 유일한 문제는 숫자 앞에 오는 0입니다. 글로브를 작성하고 그 목록을 얻는 올바른 방법을 찾아 내지 못합니다. 세 번째 목록은 0을 채우는 것이 쉽지 않기 때문에 (s3 = glob.glob ('sync_ [1601-2400] .tif') 다른 두 개는 앞쪽에 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

에서 ['으로 fnmatch()'구문 (https : //로 문서를. python.org/2/library/fnmatch.html)은'glob'에 의해 사용되는데 거의 정교하지 않습니다. –

답변

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) 

하지만 간단한 목록 함축이 부착 등의 작업에 대해 너무 잘입니다 : 당신은 한 번만 반복하고에 추가 것을 교환하여이 모든 조금 더 효율적으로 만들 수 있습니다.

+0

모든 파일이'sync_'는 아니며'sync999'와'sync 000'도 있습니다; 그것이 원래 질문의 오타가 아니라면. –

+0

@BurhanKhalid : globbing에서의 샘플 시도는 내가 사용했던 패턴을 사용합니다. 예외가 오타라고 가정합니다. –

+0

@BurhanKhalid 예, 죄송합니다. 그건 실수 였어. 답장을 보내 주셔서 감사합니다. 내가 원래 솔루션에 가깝기 때문에이 대답을 받아 들일 것이고 나는 단지 3 줄로 할 수있다. – user20408

0

하기 위해 가장 좋은 방법은 다음과 같습니다

  1. 글롭 sync
  2. 정렬 800
의 조각으로 수 구성 요소
  • 분할 그것을 기준으로 목록로 시작하는 모든 파일

    이미 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_이기 때문에 10, 다음에 위의 코드를 단순화 할 수 있습니다

    files = glob.glob('sync_*.tif') 
    sorted_files = sorted(files, key=lambda x: int(x.split('_')[1])) 
    in_batches = list(grouper(sorted_files, 800)) 
    
  • +0

    감사합니다. 이것은 또한 실행 가능한 솔루션입니다. 투표를 시도했지만 충분한 평판이 없습니다. 다시 한 번 감사드립니다. – user20408

    관련 문제