# newbie question: for loop within for loop confusion

Paul Hankin paul.hankin at gmail.com
Mon Jun 16 08:17:04 CEST 2008

```On Jun 16, 2:35 pm, takayuki <lawtonp... at gmail.com> wrote:
> def hasnolet2(avoid):
>         fin = open('animals.txt')
>         for line in fin:
>                 word = line.strip()
>
>         length = len(avoid)
>         x = 0
>         noprint = 0
>
>         while length -1 >= x:
>                 if avoid[x] in word:
>                         noprint = noprint + 1
>                 x = x + 1
>
>         if noprint == 0:
>                 print word

There seems to be an indendation problem (presumably the code from
length = len(avoid) onwards should be inside the loop). But apart from
that, we can try to make this more 'pythonic'.

First, python has a 'for' statement that's usually better than using
while. We use the 'range' function that produces the numbers 0, 1, ...
length - 1, and x takes the value of these in turn.

Here's the last bit of your code rewritten like this:

noprint = 0

for x in range(length):
if avoid[x] in word:
noprint += 1

if noprint == 0:
print word

But better, rather than using 'x' as an index, we can loop over
letters in avoid directly. I've changed 'noprint' to be a boolean
'should_print' too here.

should_print = True
for letter in avoid:
if letter in word:
should_print = False

if should_print:
print word

We can eliminate 'should_print' completely, by using 'break' and
'else'. A break statement in a loop causes the loop to end. If the
loop doesn't break, the 'else' code is run when the loop's over.

for letter in avoid:
if letter in word:
break
else:
print word

This is almost the same as your original code, but the 'else' is
attached to the 'for' rather that the 'if'!

Finally, in Python 2.5 you can write this:

if not any(letter in word for letter in avoid):
print word

I think this is the best solution, as it's readable and short.

--
Paul Hankin

```