2010-06-09 4 views
0

os.walk 문서 (http://docs.python.org/library/os.html? highlight = os.walk # os.walk)는 디렉터리 목록에서 원하지 않는 디렉터리를 제거하여 건너 뛸 수 있다고 말합니다. 문서의 명시적인 예 :파이썬의 os.walk에 오류가 있습니까?

import os 
from os.path import join, getsize 
for root, dirs, files in os.walk('python/Lib/email'): 
    print root, "consumes", 
    print sum(getsize(join(root, name)) for name in files), 
    print "bytes in", len(files), "non-directory files" 
    if 'CVS' in dirs: 
     dirs.remove('CVS') # don't visit CVS directories 

다른 동작 (ActivePython 2.6.2 사용)이 있습니다. 즉 코드 :

DIR: two 
Removing: two 
DIR: thr33 
Removing: thr33 
DIR: keep_me 
DIR: keep_me_too 
DIR: keep_all_of_us 
ROOT: \\mach\dirs 
ROOT: \\mach\dirs\ONE 
ROOT: \\mach\dirs\ONE\FurtherRubbish 
ROOT: \\mach\dirs\ONE\FurtherRubbish\blah 
ROOT: \\mach\dirs\ONE\FurtherRubbish\blah\Extracted 
ROOT: \\mach\dirs\ONE\FurtherRubbish\blah2\Extracted\Stuff_1 
... 

WTF :

>>> for root,dirs,files in os.walk(baseline): 
...  if root.endswith(baseline): 
...    for d in dirs: 
...      print "DIR: %s" % d 
...      if not d.startswith("keep_"): 
...        print "Removing %s\\%s" % (root,d) 
...        dirs.remove(d) 
... 
...  print "ROOT: %s" % root 
... 

나는 출력을 얻을? \\mach\dirs\ONE가 제거되지 않은 이유는 무엇입니까? 그것은 분명히 "keep_"로 시작하지 않습니다.

답변

5

목록을 수정하는 중이므로 dirs을 반복 처리해야합니다. ONE은 방금 건너 뛰었으며 결코 보지 않았습니다. 비교 :

>>> a = [1, 2, 3] 
>>> for i in a: 
    if i > 1: 
     a.remove(i) 


>>> a 
[1, 3] 
+0

고 말했다 무엇. 위 예제에서 그들이 반복을하기 전에'dirs'리스트를 수정하고 있음을 주목하십시오. – jathanism

+0

@ jathanism : 그들은 "dirs"을 반복하지 않습니다.) – SilentGhost

+0

예제 코드에는 없습니다. 그러나 그것이 내 포인트라고 생각했습니다. – jathanism

2

dirs 목록에서 제거하지 않았습니다. 그랬다면, 당신은 당신의 "지우기"프린트를 보았 겠지, 그렇지?

for d in dirs에서 for d in list(dirs)으로 변경하여 dirs 목록에서 안전하게 항목을 제거하고 반복하는 동안 항목을 제거하십시오.

아니면 그냥 쓸 수 :

dirs[:] = [d for d in dirs if not d.startswith("keep_")] 
+0

'list (dirs)'를 사용하여 첫 번째 제안을했지만 목록 이해는 변경에 영향을 미치지 않았습니다. –

+1

@Mike :'os.walk'가 원래 목록을 참조하기 때문에, 목록 이해가 작동하기 위해서는 다음을해야합니다 :'dirs [:] = [d가 아니라면 dirs의 d에 대해 d.startswith ("keep _") – SilentGhost

+0

오, 그래. 내 대답을 업데이트 할게. – FogleBird