[Tutor] while else, for else
Magnus Lycka
magnus@thinkware.se
Tue, 15 Oct 2002 12:07:00 +0200
At 09:30 2002-10-14 -0400, Blake.Garretson@dana.com wrote:
>I have been using Python for 3+ years now, and I have yet to see regular
>use of the "while else" or "for else" constructs. I personally *never* use
>them, and unless I haven't read enough source code from other people, I
>haven't seen evidence that anybody else uses them very often either.
I use them now and then. It's a bit like
try...except in cases where you know that
you should break out of the loop if all
goes as expected:
Like this excerpt from a large program:
for c in condIndex.findByMainName(name):
if c.system =3D=3D system:
imp =3D c
break
else:
noObject =3D NothingObject(system)
imp =3D Condition(name, 'C', noObject, system, '')
If I find a Condition 'c' with a given name belonging
to a given system, I use that. Otherwise, I make a new
Condition (with a dummy Object).
Without for...else I would have done:
imp =3D None
for c in condIndex.findByMainName(name):
if c.system =3D=3D system:
imp =3D c
break
if imp is None:
noObject =3D NothingObject(system)
imp =3D Condition(name, 'C', noObject, system, '')
Just one more line of code, but once you get used
to the concept of for/while...else, the first version
is much easier to read. It reads more like prose, with
a better flow and less surprise. Why should I do 'imp=3DNone'
if I never really wan't imp to be None? Besides, I assume
this will be more bytecode. The if-test has to be made.
for/while...else might provide some performance improvement.
A little further down:
row =3D 0
for f in self.getCatalog(Function):
if f =3D=3D function and self.getProcessMatrixRow(f, row):
# We found a row to copy
break
row +=3D 1
else:
return
procRow =3D self.getProcessMatrix()[row]
for col in range(len(procRow)):
code =3D procRow[col][0]
self.changeProcessMatrix(row, col, code)
Since the function ended here, it might as well have been:
row =3D 0
for f in self.getCatalog(Function):
if f =3D=3D function and self.getProcessMatrixRow(f, row):
# We found a row to copy
procRow =3D self.getProcessMatrix()[row]
for col in range(len(procRow)):
code =3D procRow[col][0]
self.changeProcessMatrix(row, col, code)
return
row +=3D 1
Perhaps the second is better? It's just a matter
of style. I found it simpler when I wrote it to see
it as a two step process: First find the row, and
then process it. The first version emphasizes this
separation, and also leads to less indentation. Not
a huge win in this case, but I guess I just wrote it
like I did because I thought of it like two separate
steps. Also, the second versions seems to suggest
that there is a nested loop here, and that's not
really the case, since the inner loop will only run
once.
--=20
Magnus Lyck=E5, Thinkware AB
=C4lvans v=E4g 99, SE-907 50 UME=C5
tel: 070-582 80 65, fax: 070-612 80 65
http://www.thinkware.se/ mailto:magnus@thinkware.se