Conditional operator mis-matching - python

When I execute in python following code
print(0<5<2)
It gives False as output
but same thing in C++
std::cout<<(0<5<2);
returns True
Why this contradiction?

In Python, 0 < 5 < 2 is equivalent to 0 < 5 and 5 < 2.
In C++, it is equivalent to static_cast<int>(0 < 5) < 2.
The Python shorthand is originally inspired by mathematics, but has been so generalized that you can write really strange stuff, like
>>> 1 < 5 in [2,3,4]
False
>>> 1 < 5 in [2,3,5]
True
and confuse all your friends.

Because they are different language that has different syntax and work differently.
In the case of c++, the statement is evaluated from left to right.
0<5 == true
true < 2, this will trigger an implicit conversion from true to 1
1 < 2 == true, which is the end result
Python has different rules for how the language works.
I don't know them, but clearly they lead to different result in this case.

Related

Strange Logic Behavior with Variable and Number

Say I define a and b as follows:
a = 1
b = 1
Then I test:
a == 1
#True
5>4
#True
a==1 & b==1
#True
5>4 & 4>3
#True
a==1 & 5>4
#False
What is going on with the last one? I would like to be able to test the last inequality and get the result of True.
In Python & is for bit operations with numbers, not logic. Use and and or instead.
Unlike C, all comparison operations in Python have the same priority, which is lower than that of any arithmetic, shifting or bitwise operation. Also unlike C, expressions like a < b < c have the interpretation that is conventional in mathematics:
Which means:
a==1 & 5>4 is equal to
a == ( 1 % 5 ) > 4
a == 1 > 4
True > 4
False

python XOR for two integers

Coming from a Java background into Python and working my way through CodingBat (Python > Warmup-1 > pos_neg) the following confused me greatly:
>>> True ^ False
True
>>> 1<0 ^ -1<0
False
I appreciate the following:
>>> (1<0) ^ (-1<0)
True
But what is python interpreting 1<0 ^ -1<0 as to return false?
^ has higher precedence than <.
Thus, what is being evaluated is actually 1 < -1 < 0, where 0 ^ -1 = -1
And thus you rightly get False, since the inequality clearly does not hold.
You almost never have to remember the precedence table. Just neatly use parenthesis.
You might want to check this out as well, which discusses an identical situation.
0 ^ -1 equals -1. 1 < -1 < 0 is False since 1 is greater than -1. Python chains relational operators naturally, hence 1 < -1 < 0 is equivalent to (1 < -1) and (-1 < 0).

Python Implicit if statement with variable assignment -- How does this work? [duplicate]

This question already has answers here:
Is it Pythonic to use bools as ints?
(7 answers)
Closed 8 years ago.
I started learning python within the last month. I recently came across a code example where a counter in the code was incremented based on a condition. The way the author did it was:
x = 0
x += [-1, 1][a == b]
From testing this works the same as if you used an if a==b: increment, else: decrement.
I can't find this syntax anywhere else I've looked in the python documentation. It seems quite powerful and allows a variety of conditional assignments and aids conciseness.
Is there a reason I shouldn't use this structure also what is the structure doing?
The Zen of Python says:
Explicit is better than implicit.
Simple is better than complex.
Readability counts.
Stick to the more explicit, readable and widely used version:
x += 1 if a == b else -1
[a == b] evaluates to False or True which are effectively 0 or 1, so then that's used as the index into [-1, 1]...
So when a==b you get [-1, 1][1] (which is 1) or where they're not equal you get [-1, 1][0] (which is -1), the respective value is then added to x.
Some would call it a hack, and it can be difficult to read (as evidenced by this question) but it's equivalent to:
x = 0
if(a == b):
x += 1
else:
x -= 1
Because the integer version of the (boolean) result of a == b is 0 or 1.

What does `<>` mean in Python?

I'm trying to use in Python 3.3 an old library (dating from 2003!). When I import it, Python throws me an error because there are <> signs in the source file, e.g.:
if (cnum < 1000 and nnum <> 1000 and ntext[-1] <> "s":
...
I guess it's a now-abandoned sign in the language.
What exactly does it mean, and which (more recent) sign should I replace it with?
It means not equal to. It was taken from ABC (python's predecessor) see here:
x < y, x <= y, x >= y, x > y, x = y, x <> y, 0 <= d < 10
Order tests (<> means 'not equals')
I believe ABC took it from Pascal, a language Guido began programming with.
It has now been removed in Python 3. Use != instead. If you are CRAZY you can scrap != and allow only <> in Py3K using this easter egg:
>>> from __future__ import barry_as_FLUFL
>>> 1 != 2
File "<stdin>", line 1
1 != 2
^
SyntaxError: with Barry as BDFL, use '<>' instead of '!='
>>> 1 <> 2
True
It means NOT EQUAL, but it is deprecated, use != instead.
It's worth knowing that you can use Python itself to find documentation, even for punctuation mark operators that Google can't cope with.
>>> help("<>")
Comparisons
Unlike C, all comparison operations in Python have the same priority,
which is lower than that of any arithmetic, shifting or bitwise
operation. Also unlike C, expressions like a < b < c have the
interpretation that is conventional in mathematics:
Comparisons yield boolean values: True or False.
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).
The forms <> and != are equivalent; for consistency with C,
!= is preferred; where != is mentioned below <> is also
accepted. The <> spelling is considered obsolescent.
See http://docs.python.org/2/reference/expressions.html#not-in
It is an old way of specifying !=, that was removed in Python 3. A library old enough to use it likely runs into various other incompatibilities with Python 3 as well: it is probably a good idea to run it through 2to3, which automatically changes this, among many other things.
Use != or <>. Both stands for not equal.
[Reference: Python language reference]
The comparison operators <> and != are alternate spellings of the same operator. != is the preferred spelling; <> is obsolescent.

Evaluating numerical expressions

Can someone explain to me why when evaluating numerical expressions Python as a result of evaluation returns the last thing that was evaluated?
For example:
3 and 5
evaluates to
5
Another question I have is why is it even evaluating these expressions, when I try to check:
3 == True
I get False but when I evaluate:
3 and 5
and get 5 as a result it obviously( I think) thinks that 3 evaluates to True since it wouldn't continue evaluating if it thought otherwise( I might be wrong here).
In contrast when I evaluate:
0 and 3
I get 0, what I think is happening is that Python checks whether 0 is True, decides it's not and spits it out.
I'm sorry if it all sounds a bit chaotic but I stumbled across this in my book and was curious if there is something I'm missing.
Yes, in python any value is either truthy or falsy. Every integer is truthy except for 0. With the boolean operators or and and, python returns the last expression it evaluates, for example 3 or 5 will return 3 as python first sees that 3 is truthy and does not have to evaluate 5 and returns 3.
In 0 and 5, 0 is falsy and so python does not evaluate the next expression and returns 0.
The reason 5 == True gives False as 5 does not equal true, it just acts truthy in boolean expressions. bool(5) == True gives True as this explicitly converts the integer to a boolean.
From the Python Reference:
The expression x and y first evaluates x; if x is false, its value is returned;
otherwise, y is evaluated and the resulting value is returned.
If you had said
0 and 5
the value of the first thing evaluated (0) would have been returned.
For the second question, 3 obviously evaluates to true when treated as a boolean, but the == operator does not coerce its arguments to boolean prior to comparison.
How boolean operations work
See documentation on boolean operations. They work in the following way:
a or b returns the first element that is evaluated as True, so in case of 0 or 3 it will be 3, and in case of 3 or 5 it will be 3 also,
a and b returns the first element evaluated as False, otherwise (in case all the elements are evaluated as True) the last element is returned, so 0 and 3 will became 0 and 3 and 5 will became 5,
Solution
But there is a solution to your problem. Just cast the result into boolean using bool():
>>> bool(0 or 3)
True
>>> bool(3 or 5)
True
>>> bool(0 and 3)
False
>>> bool(3 and 5)
True
Did it help?
EDIT:
Another solution
Actually I think in your case there may be even a better solution to your problem. See this:
bool(a or b) can be replaced by any([a, b]), and
bool(a and b) can be replaced by all([a, b]),
and I now believe this is a more reasonable solution.

Categories