weird behaviour in python if clause [duplicate]

大兔子大兔子 提交于 2019-12-02 14:53:26

问题


I wrote a simple little rock, paper, scissors game in python and had some difficulties with an if clause, here's the relevant code:

def play():
    user = str(input("rock, paper or scissors? Choose one: "))
    print("You chose", user)

    if user == "paper" or "Paper":
        paper()

    elif user == "rock" or "Rock":
        rock()

    elif user == "scissors" or "Scissors":
        scissors()

    else:
        print("Sorry, your choice was not valid, try again please.")
        play()

Now, no matter whether I chose rock, paper or scissors, it would always trigger the first condition, leading me to the paper function. I actually already solved it, it was the second condition I put in the if clauses, the "Paper", "Rock" and "Scissors", which I put there for the case people uppercase the first letter. My question is, why did the second condition trigger the first if clause? When I removed all the second strings, it worked perfectly fine, the rock triggered the second condition, the scissors one triggered the third and so on. I hope this is not too confusing. Thanks.


回答1:


user == "paper" or "Paper"

is always true. The or operator tests the expressions on either side of itself, and if either is true, the result of the or is also true. Your test above checks (up to) two things:

  • Is the expression user == "paper" true? If so, the whole expression is true, so don't check the second part, because True or x is always true regardless of the value of x.
  • Is the expression "Paper" true? And because non-zero-length strings are true in Python, this part is always true.

So even if the first part is false, the second part is always true, so the expression as a whole is always true.

You wanted something like this:

user == "paper" or user == "Paper"

or, better yet:

user in ("paper", "Paper")

or, best of all:

user.lower() == "paper"



回答2:


You can also do this with lists and in:

if user in ["paper", "Paper"]:
    paper()

or using regex:

import re
user = 'paper'
if re.match('papers?', user):
    paper()
elif re.match('[Rr]ock', user):
    rock()

with regexes you can also do case-insensitive match:

import re
user = 'paper'
if re.match('papers?', user, re.I):
    paper()

which will match all: paper, PapER, PaperS, ...




回答3:


you want:

if user == "paper" or user == "Paper":

Same for the others as well.

If you just put

if "Paper":

Python evaluates it as if this_value_is_true. Same with the code you have basically evaluates to "if user variable equals 'paper' or True" which would always be tue.




回答4:


I believe I know where your problem comes from:

if user == "paper" or user == "Paper":

That should fix the problem




回答5:


This:

if user == "paper" or "Paper":

… is parsed as this:

if (user == "paper") or "Paper":

If user actually is equal to "paper", that's if True or "Paper", which is True.

Otherwise, that's if False or "Paper", which is "Paper".

Since True and "Paper" are both truthy, the if always happens.




回答6:


if user == "paper" or "Paper":

Actually evaluates to:

(user == "paper")  or "Paper"

i.e (result of user == "paper") or "Paper"

So the 2 possibilities here are:

  1. True or "Paper"
  2. False or "Paper"

In first case it returns True and in the second one it returns "Paper".

As "Paper" is a True value(all non-empty strings are True) so this condition is always True.

You should use:

if user.lower() == "paper"


来源:https://stackoverflow.com/questions/17284495/weird-behaviour-in-python-if-clause

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!