newbie question: for loop within for loop confusion

MRAB google at mrabarnett.plus.com
Mon Jun 16 22:34:27 CEST 2008


On Jun 16, 7:17 am, Paul Hankin <paul.han... at gmail.com> wrote:
> 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.
>
Alternatively, you could use sets:

if not(set(word) & set(avoid)):
    print word

(parentheses added for clarity.)



More information about the Python-list mailing list