Why is this else: pass needed for processing to continue?
Solution 1
I'm going to answer my own question and eventually accept it. The seemingly odd behavior described was caused by an subtle indention problem, the possibility of which was first brought to my attention by user @delnan. Because it was invisible, initially I didn't think it could be the case, but eventually found it after more investigation. The details of which have been added to the end of my question.
Solution 2
You don't need it. I ran the following 2 scripts:
#test1.py
import os
source_dir = '.'
ext = '.txt'
for dirName, subdirList, fileList in os.walk(source_dir):
if not any(os.path.splitext(fileName)[1].lower() == ext for fileName in fileList):
print ' skipping "{}"'.format(dirName)
continue
else: # why is this clause needed to continue this iteration of a loop?
print 'contains "{}"'.format(dirName)
pass
print 'processing "{}" which has "{}" files'.format(dirName, ext)
and
#test2.py
import os
source_dir = '.'
ext = '.txt'
for dirName, subdirList, fileList in os.walk(source_dir):
if not any(os.path.splitext(fileName)[1].lower() == ext for fileName in fileList):
print ' skipping "{}"'.format(dirName)
continue
#else: # why is this clause needed to continue this iteration of a loop?
# print 'contains "{}"'.format(dirName)
# pass
print 'processing "{}" which has "{}" files'.format(dirName, ext)
I ran them as:
python test1.py > junk.log
python test2.py > junk.log2
Here's the first couple lines of junk.log
:
test $ head junk.log
processing "." which has ".txt" files
skipping "./new"
skipping "./unum"
processing "./unum/kiv-unum-409befe069ac" which has ".txt" files
skipping "./unum/kiv-unum-409befe069ac/build"
skipping "./unum/kiv-unum-409befe069ac/build/bdist.macosx-10.3-fat"
skipping "./unum/kiv-unum-409befe069ac/build/lib"
skipping "./unum/kiv-unum-409befe069ac/build/lib/tests"
skipping "./unum/kiv-unum-409befe069ac/build/lib/unum"
skipping "./unum/kiv-unum-409befe069ac/build/lib/unum/units
Notice the presence of "processing" lines.
Then I diff
the output:
diff junk.log junk.log2
with the following results:
0a1
> contains "."
3a5
> contains "./unum/kiv-unum-409befe069ac"
14a17
> contains "./unum/kiv-unum-409befe069ac/docs"
16a20
> contains "./unum/kiv-unum-409befe069ac/nose-1.2.1-py2.7.egg/EGG-INFO"
19a24
> contains "./unum/kiv-unum-409befe069ac/nose-1.2.1-py2.7.egg/nose"
30a36
> contains "./unum/kiv-unum-409befe069ac/Unum.egg-info"
Note that there are no differences on the "processing" lines.
martineau
Most of my interest and expertise is in software written in Python and C/C++. I've been writing computer code most of my adult life, beginning my senior year in high school working at a part-time NASA job utilizing a CDC 7600 (generally regarded as the fastest supercomputer in the world at the time), punched cards, and FORTRAN IV, soon followed by a mixture of Applesoft BASIC and 6502 assembler on a 64K Apple II personal computer purchased while attending college in California. I currently live in the state of Washington in the USA, at the base of the western foothills of the Cascade mountains, near a small town named Enumclaw, which lies south of Seattle and east of Tacoma. NOTE: Please don't contact me via LinkedIn to ask to be added to my network.
Updated on June 13, 2022Comments
-
martineau almost 2 years
Can someone explain why the
else: pass
shown below is needed in order for the rest of the code (the finalprint 'processing...
statement) to be executed? Note theprint
in theelse
was put there just so I could tell that execution was indeed taking that path.It seems like that should happen whenever the
continue
isn't executed since code in theelse
does nothing. However, if I leave theelse
out, nothing further in thefor
loop appears to be executed when the condition is False -- when files with the extension do exist in the directory -- which doesn't make sense to me. The docs saycontinue
"continues with the next cycle of the nearest enclosing loop", fine, but if one is not executed, shouldn't processing proceed to the next statement?import os source_dir = r'C:\Downloads' ext = '.mp3' for dirName, subdirList, fileList in os.walk(source_dir): if not any(os.path.splitext(fileName)[1].lower() == ext for fileName in fileList): print ' skipping "{}"'.format(dirName) continue else: # why is this clause needed to continue this iteration of a loop? print 'contains "{}"'.format(dirName) pass print 'processing "{}" which has "{}" files'.format(dirName, ext)
Mystery Solved
The seemingly strange behavior was due to an indentation problem which is not visible in the code above nor normally in my text editor. It turned out that the last
print
statement was indented by 3 spaces then a tab, which makes it appear to align with theelse
, but in fact it either follows thepass
in theelse
if it's there, or follows thecontinue
in the first part of theif
. Obviously confusing me a great deal.Here's a screenshot of the code in my text editor with its "show space/tabs" option turned on. The red dots represent spaces and the red right guillemet (
»
) represents a tab character: