while loop - multiple condition

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Oct 13 00:56:02 CEST 2014


Tim Chase wrote:

> On 2014-10-12 22:16, Marko Rauhamaa wrote:
>> is equivalent with
>> 
>>     while ans.lower()[0] != 'y':
>>          ans = input('Do you like python?')
> 
> And still better improved with
> 
>   while ans[:1].lower() != 'y':
>     ans = input('Do you like python?')


The intention is to loop forever until the victim breaks down and accepts
that they like Python, by entering "yes" or "y". I'm pretty sure that
entering "yellow" or "you've got to be kidding" should not break the loop.

When you have multiple clauses in the condition, it's easier to reason about
them if you write the clauses as positive statements rather than negative
statements, that is, "something is true" rather than "something is not
true", and then use `not` to reverse it if you want to loop *until* the
overall condition is true.

When checking for equality against multiple values, instead of:

    x == a or x == b or x == c

it is usually easier to use `in`:

    x in (a, b, c)


So we have:

# loop so long as the victim answers "yes" or "y"
while ans.lower() in ('yes', 'y'):
    ans = input('Do you like python? Well, do you?')

# loop until the victim answers "yes" or "y"
while not (ans.lower() in ('yes', 'y')):
    ans = input('Do you like python? Well, do you?')


both of which work fine if the user stays mum by entering the empty string.

You can also write:

while ans.lower() not in ('yes', 'y'):
    ans = input('Do you like python? Well, do you?')


if you prefer. In my opinion, that's the most readable version of all.

One last note: if you are using Python 3.3 or better, you can support
international text better by using the casefold() method rather than
lower(). In this case, it won't make a difference, but the technically
correct method for doing case-insensitive comparisons is to casefold both
strings rather than lower- or upper-case them.


-- 
Steven




More information about the Python-list mailing list