2011-01-07 9 views
21

먼저 아래 문제에 대한 해결책을 찾고있을 때 stackoverflow에서 찾을 수 없기 때문에 먼저 게시하고 있습니다. 그래서 여기 지식베이스에 조금 더 추가하고 싶습니다.숫자로 파일을 정렬하는 방법은 무엇입니까?

디렉토리의 일부 파일을 처리해야하며 파일을 숫자순으로 정렬해야합니다. 특히 lambda 패턴을 사용하여 - - I 정렬에 몇 가지 예를 발견 wiki.python.org에서, 나는 이것을 함께 넣어 :

#!env/python 
import re 

tiffFiles = """ayurveda_1.tif 
ayurveda_11.tif 
ayurveda_13.tif 
ayurveda_2.tif 
ayurveda_20.tif 
ayurveda_22.tif""".split('\n') 

numPattern = re.compile('_(\d{1,2})\.', re.IGNORECASE) 

tiffFiles.sort(cmp, key=lambda tFile: 
        int(numPattern.search(tFile).group(1))) 

print tiffFiles 

난 여전히 파이썬 오히려 새로 온 사람과있을 경우 지역 사회를 부탁드립니다 코드 개선 (lambda 삭제), 성능, 스타일/가독성을 향상시킬 수있는 모든 개선 사항은 무엇입니까?

는 재커리이는 "자연 정렬"또는 (기본값 정렬을 사전 편찬에 반대,) "인간의 분류"라고

+2

+1 올바른 질문 제목입니다. – systemovich

+4

당신이하고있는 일을하는 _right_ 방법은 질문 비트에서 질문을 한 다음 대답을 답변 비트에 추가하는 것입니다. 그렇다면 뒤로 앉아서 기다리십시오 ... – paxdiablo

+0

@paxdiablo : 지침에 감사드립니다 ... 답변을 드릴 수있는 FAQ를 읽었으며 역학에 대해 확실히 확신하지 못했습니다. 다음에 바로 할께. –

답변

30

을 주셔서 감사합니다. Ned B wrote up a quick version of one.

import re 

def tryint(s): 
    try: 
     return int(s) 
    except: 
     return s 

def alphanum_key(s): 
    """ Turn a string into a list of string and number chunks. 
     "z23a" -> ["z", 23, "a"] 
    """ 
    return [ tryint(c) for c in re.split('([0-9]+)', s) ] 

def sort_nicely(l): 
    """ Sort the given list in the way that humans expect. 
    """ 
    l.sort(key=alphanum_key) 

그것은 당신이 무슨 일을하는지와 유사하지만 아마도 조금 더 일반화.

+1

감사합니다, Daniel! 이것은 내가 찾고 있었던 바로 그 것이다. 나는 당신이 포함했던 링크를 따라 갔다. 그리고 토끼 구멍의 아래에서 나는 갔다. .. weeee! 나는 try/except와 (물론) pre-compiling regexps의 성능에 대해 조금 배웠다. :) –

+0

우리는 목록 이해보다는 발전기를 반환하면이 작동합니까? –

+0

음수의 내장 숫자를 올바르게 처리하지 못합니다. – martineau

5

정렬 방법에 key=을 사용하는 경우 최신 버전의 Python에서 제거 된 cmp을 사용하면 안됩니다. key은 레코드를 입력으로 사용하고 목록을 정렬하려는 순서대로 비교할 개체를 반환하는 함수와 동일해야합니다. 람다 함수 일 필요는 없으며 독립 실행 형 함수로 더 명확 할 수 있습니다. 또한 정규식을 평가하는 속도가 느려질 수 있습니다.

당신은 같은 것을 시도 할 수있는 분리하고 파일 이름의 정수 부분을 반환하려면 다음 튜플에

def getint(name): 
    basename = name.partition('.') 
    alpha, num = basename.split('_') 
    return int(num) 
tiffiles.sort(key=getint) 
+0

감사합니다. 나는 당신의 설명에 정말로 감사한다. 매우 이해할 수있다. - Zachary –

+0

@Don O'Donnell 오류가 발생했습니다. _AttributeError : 'tuple'객체에 'split'속성이 없습니다. 따라서 코드를 약간 수정했습니다 : 'basename = name.partition ('.')' basename = name.split ('.')'(** 중요! 점없이 파일 이름에 대해서만 ** 작동) alpha, num = basename.split ('_')' . 슬쩍 ('_')'어쨌든, 당신은 내 하루를 보냈습니다. 감사! – KnightWhoSayNi

0

파티션 결과

def getint(name): 
    (basename, part, ext) = name.partition('.') 
    (alpha, num) = basename.split('_') 
    return int(num) 
+0

실제로 해봤습니까? '(a, b, c) = 'ayurveda_11.tif'.split ('. '), ValueError : 압축을 풀려면 2 개 이상의 값이 필요합니다 .' –

5

그냥 사용

tiffFiles.sort(key=lambda var:[int(x) if x.isdigit() else x for x in re.findall(r'[^0-9]|[0-9]+', var)]) 

은 try/except를 사용하는 것보다 빠릅니다.

관련 문제