2012-06-01 1 views
0

반복 할 여러 확장명을 가진 파일 목록을 만들려고합니다. 스택 오버플로에 대한 답변의 대부분은 람다를 사용하여 필터링하는 것이지만이 경우 어떻게 작동하는지 잘 모르겠습니다 (반복이 설정되는 방식 때문). 지금까지 나는 분명히 문제가 list.remove가 첫 번째 인스턴스 만이 아니라 모든 인스턴스를 제거한다는 것입니다Python : 필터를 사용하는 목록에서 여러 값을 제거하는 경우

import fnmatch 

excluded = ['*.py', '*.py~'] 

fileNames = [] 

for fileName in os.listdir('.'): 
    fileNames.append(fileName) 
    print fileNames 

for p in excluded: 
    if fnmatch.fnmatch(fileName, p): 
     fileNames.remove(fileName) 
     print fileNames 

있습니다. 이 문제를 해결하는 가장 효율적인 방법은 무엇이라고 생각하십니까?

감사합니다.

+0

를 사용

filtered = [x for x in os.listdir('.') if not re.search(r'\.py~?$', x)] 

또는 inden을 의미하지 않았다. 인쇄 문. 그렇지 않으면 무언가를 추가 할 때마다 전체 목록을 다시 인쇄합니다. – Matt

답변

4

)) 지능형리스트를 사용

filtered = [x for x in os.listdir('.') if not any(fnmatch.fnmatch(x, p) for p in excluded)] 

을 다른 방법으로는, 컴팩트 코드는 정규 표현식을 사용하여 : 단순히 아마 당신을 endswith

excluded = ('.py', '.py~') 
filtered = [x for x in os.listdir('.') if not x.endswith(excluded)] 
+1

그 중 하나가 아마도 최고입니다. – Matt

2

사용은이 list comprehension : 당신은뿐만 아니라 any()를 사용하여이 작업을 훨씬 더 잘 할 수

for p in excluded: 
    fileNames = [filename for filename in fileNames if not fnmatch.fnmatch(filename, p)] 

: os.listdir()와 같이 만들고있는 목록이 무의미한 것을

fileNames = [filename for filename in fileNames if not any(fnmatch.fnmatch(filename, p) for p in excluded)] 

참고 목록을 반환 어쨌든 fileNames = os.listdir()을 사용하여 동일한 결과를 얻거나 목록 이해에 배치 할 수도 있습니다.

fileNames = [filename for filename in os.listdir() if not any(fnmatch.fnmatch(filename, p) for p in excluded)] 

목록을 작성할 때 값을 편집하려면 목록 이해로 값을 편집 할 수 있습니다.

또 다른 대안은 fnmatch 모듈에 fnmatch.filter()입니다.

2
def includefilename(fileName): 
    for ex in excluded: 
     if fnmatch.fnmatch(fileName, ex): 
      return False 
    return True 

fileNames = [fileName for fileName in fileNames if includefilename(fileName)] 
+1

함수를 반대로 바꾸고 마지막 줄을'fileNames = filter (includefilename, fileNames)'로 바꿀 수도 있습니다. – Matt

+0

@Matt - 사실! 변경됨. –

관련 문제