How to check if exactly one of two condition is met [duplicate] - python

This question already has answers here:
How do you get the logical xor of two variables in Python?
(28 answers)
Closed 2 years ago.
I am checking wether one of two conditions applies and only one.
My question is if there is a way to have a single if statement to do this:
if x == True:
if y == False:
do_something()
elif x == False:
if y == True:
do_something()
Ideally similar to how and and or work so that it would something like:
enter code here
if x == True ° y == True:
do_something()
whereas ° is the wanted operator
do nothing if: x,y = True or x,y = False
do something if: x = True and y = False or x = False and y = True
I would appreciate any advice if this is not possible.
Thank you in advance!!

You need to use the logical operator XOR, but in this scenario, it's the equivalent of just saying
if x != y:
do_something()
As it will only be true if one of the conditions is met.
-- update --
There's also an actual XOR operator
if x ^ y:
do_something()
They will be identical in this example.

Related

Why am I getting a "Referenced before assignment" error? [duplicate]

This question already has answers here:
How can a name be "unbound" in Python? What code can cause an `UnboundLocalError`?
(3 answers)
Closed last year.
This Python program will determine whether the input array is a mountain array or not. I've found answers on stackoverflow for this same error in other programs I've made, but not this one. It seems to work without issue when a valid mountain array is the input, but I'm having issues when I change the first half of the test array to make it an invalid. Rather than it returning False, which is the goal, I'm getting this error: UnboundLocalError: local variable 'y' referenced before assignment. Also, I was getting the same error for the z variable, so I added the else statements and it fixed it. Can't figure out why it didn't fix the y variable as well. Here's my code:
def validMountainArray(arr):
maxElem = max(arr)
maxIndex = arr.index(maxElem)
if len(arr) < 3:
return False
else:
beginning = arr[:maxIndex]
end = arr[maxIndex + 1:]
for i in range(1, len(beginning) - 1):
if beginning[i + 1] > beginning[i]:
y = True
else:
y = False
for i in range(1, len(end) - 1):
if end[i + 1] < end[i]:
z = True
else:
z = False
if y == True and z == True:
return True
else:
return False
Those for-loops aren't guaranteed to be executed. It's possible that the range could end up with 0 numbers in it, and thus no loop will occur and y and/or z will never be assigned. To fix this, define those variables as False at the start of the function.
def validMountainArray(arr):
y = False
z = False
maxElem = max(arr)
maxIndex = arr.index(maxElem)
# etc

Order of operation evaluation in condition in Python

If I have something like a = [1,2,3] and I write a statement like 1 in a == True, that appears to evaluate to false.
However, if I write (1 in a) == True, that evaluates to true.
I am slightly confused about how Python evaluates the first statement to reach false in the end.
Both == and in are considered comparison operators, meaning that operator chaining comes into effect:
Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).
This chaining is what allows you to write:
if 0 <= x < 20: # meaning: if x >= 0 and x < 20:
Hence the expression 1 in a == True is chained as 1 in a and a == True and, since the right side of that and evaluates to false, the entire expression is false.
This chaining does not occur when you "isolate" part of the expression with parentheses, which is why (1 in a) == True acts as you expect.
Having explained that, comparing a boolean value with True (or False for that matter) is not really something you should be doing anyway, since that leads to logically infinite scenarios like:
if (((a == 7) == True) != False) == True # 'a == 7' already a boolean.
Far better just to use one of:
if expression # if comparing with True
if not expression # if comparing with False

Python != giving unexpected results [duplicate]

This question already has answers here:
Why does the expression 0 < 0 == 0 return False in Python?
(9 answers)
Closed 5 years ago.
I came across a very confusing problem on a website for speed learning Python. It's about the operand != and how it works. The result/outcome of using != between 3 operands baffles me and my classmates. We have tried to search around and couldn't find any discussion/explanation on this. Please help.
Specifically, please see below:
True != False != 1
output: True
True != False != True
output: True
True is not False is not True
output: True
Breaking down the first statement step by step, True!=False should be evaluated first to yield a True. This True is then compared against 1 using != again. True != 1 should yield a False. Therefore the entire statement should evaluate to False! But instead a True is produced.
Breaking down the second statement step by step, True!=False should yield True, then this True != True should yield a False. The statement should evaluate to False !But instead a True is produced.
Likewise for the third statement.
Trying the exact same statements in Javascript and JAVA both gave the expected result - False, which makes complete sense. Python however, is the exception.
Note: We know that explicitly forcing the order of the operation by putting parentheses around two of operands gives the "right" result (which is False).We just can't understand why it's the way it is without parentheses.
Any help would be much appreciated.
It is because a != b != c is equivalent to a != b and b != c.
It is called chained comparison and you can find more info here:
https://docs.python.org/3/reference/expressions.html

Why is this python if statement not equal to true?

I was going over an assignment, and came across something that confused me, as am I not crazy good with python. Here is the code.
def main():
list = [1,2]
x = 2
if (x in list == True):
print("hi")
if (x in list):
print("Why does this proc?")
main()
I believed the output would be both, but the output is only the second if statement. I know that in C, if you had something like
if (x = 6)
That since there is only one '=' that x is now equal to 6. (As its read, if (), x = 6).
Is something similar happening to this python code? Is it checking 'list == true' first, then from there checking about x being in list?
Any insight would be greatly appreciated!
As you can see, yes, your expression requires explicit grouping:
>>> 2 in [1,2] == True
False
>>> (2 in [1,2]) == True
True
Note that, as #tavo and #MorganThrapp mention, the version without parentheses is doing a chained comparison, checking that 2 in [1,2] and then checking that [1,2] == True. The latter is false, so the full expression is also false.
By the way, don't name your variables after built-ins like list, or you won't be able to use those functions easily.
Also, you don't have to compare the result of an expression to True:
>>> 2 in [1,2]
True
Doing so is the equivalent of asking "is 'the cake is ready' a true statement?" as opposed to "is the cake ready?".

Why does this str strict comparison fail in Python? [duplicate]

This question already has answers here:
Why does comparing strings using either '==' or 'is' sometimes produce a different result?
(15 answers)
Closed 8 years ago.
I have this code in a decorator:
is_local_valid = ['system_id', 'server_id', 'sensor_id']
local_params = [x for x in is_local_valid if x in kwargs.keys() and kwargs[x].lower() is 'local'] + [y for y in args if y.lower() is 'local']
if local_params == []:
raise AssertionError("Tried to access the database from a non connected profile")
I noticed that the is infix operator for comparing two strings returns False in this case, even when kwargs[x].lower() equals to local. The == operator does return True, though. Both are str, of course.
Any clue on what's going on?
The operators is and is not test for object identity:
x is y is true if and only if x and y are the same object. x is not y yields the inverse truth value.
>>> id('local')
42745112
>>> a = {1: 'locAl'}
>>> id(a[1].lower())
53363408
They are not the same object
a is b determines whether two names a and b reference the same object (i.e. id(a) == id(b)). a == b determines whether they have equal values. It is rarely a good idea to compare strings with is; use == instead:
>>> "".join("hello")
'hello'
>>> "hello" is "".join("hello")
False
>>> "hello" == "".join("hello")
True
The only general case for comparison with is would be for None, e.g.:
if a is None:

Categories