I thought I read somewhere that python (3.x at least) is smart enough to handle this:
x = 1.01
if 1 < x < 0:
print('out of range!')
However it is not working for me.
I know I can use this instead:
if ((x > 1) | (x < 0)):
print('out of range!')
... but is it possible to fix the version above?
It works well, it is your expression that is always False; try this one instead:
x = .99
if 1 > x > 0:
print('out of range!')
Python chained comparisons work like mathematical notation. In math, "0 < x < 1" means that x is greater than 0 and less than one, and "1 < x < 0" means that x is greater than 1 and less than 0.
And. Not or. Both conditions need to hold.
If you want an "or" , you can write one yourself. It's or in Python, not |; | is bitwise OR.
if x > 1 or x < 0:
whatever()
Alternatively, you can write your expression in terms of "and":
if not (0 <= x <= 1):
whatever()
You can do it in one compound expression, as you've already noted, and others have commented. You cannot do it in an expression with an implied conjunction (and / or), as you're trying to do with 1 < x < 0. Your expression requires an or conjunction, but Python's implied operation in this case is and.
Therefore, to get what you want, you have to reverse your conditional branches and apply deMorgan's laws:
if not(0 <= x <= 1):
print('out of range!')
Now you have the implied and operation, and you get the control flow you wanted.
Related
Question asked to sum first n natural numbers.
My answer is:
def sum_numbers(x):
if x == 1:
return x
else:
return sum_numbers(x-1) + x
However, there is a more succinct:
def sum_numbers(n):
return n + sum_numbers(n-1) if n else 0
Was wondering how I should interpret the sum_numbers(n-1) if n? when does the else 0 come into play and n stop holding true? Looking at my original answer it seems its trying to say that we recurse function until x==1 before we return the entire sum?
Many thanks in advance!
The ternary operator
If you are familiar with other programming languages, python's a if b else c is expressed:
b ? a : c in C and Java;
if b then a else c in OCaml and Haskell.
?: is often called "the ternary operator", and the whole expression is called a "conditional expression" as opposed to the "conditional statement" you are familiar with.
In all cases, it is an expression that evaluates to the result of a or the result of c depending on the truth-value of b.
Inside a function, the two following fragments of code are equivalent:
if b:
return a
else:
return c
return (a if b else c)
Note that the expression is evaluated lazily, meaning that only the relevant subexpression is evaluated. For instance, the following code is correct and does not result in a ZeroDivisionError:
x = 6
y = 0
z = ((x / y) if (y != 0) else (x / 2))
print(z)
Output: 3.
Converting between int and bool
The condition used in the conditional statement n + sum_numbers(n-1) if n else 0 is simply "n". This might be unexpected, because n is a number, not a condition, right?
There is a python feature that any value can be used as a condition. This includes numbers, lists, dicts, strings, etc. In that case, "zero" or "empty" values mean false, and "nonzero" or "non-empty" values mean true. Since n is a number, "n" is the same as "n != 0" as the condition here.
Conclusion
Finally, the given piece of code is equivalent to:
def sum_numbers(n):
if n != 0:
return n + sum_numbers(n-1)
else:
return 0
The interpretation of: return n + sum_numbers(n-1) if n else 0 is this:
First split off two expressions: n + sum_numbers(n-1) and 0 because the if else should be interpreted as:
<expr1> if <cond> else <expr2>
This leaves <cond> above which is n in your expression. This is using n as the conditional, which means bool(n), which in the case of an integer means it returns False if 0 otherwise True.
So your expression means return n + sum_numbers(n-1) if n is truthy (ie non-zero) else return 0.
Note that the evaluation of n as a bool is performed before either of the other two expressions.
So the second sum_numbers is really returning the sum of 0..n
I want to do the following example in python:
x = 10
y = 8
if x-5 <= y <= x+5:
print(y)
I see that this is working, but I would like to know if it's "ok" like this, if there is a better solution or something I have to consider doing it like this.
Chained expressions are acceptable in Python:
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).
In fact, because and is lazy and the syntax is cleaner, they are preferable.
Just be aware that chained expressions take priority. For example, see Why does the expression 0 < 0 == 0 return False in Python?.
When using this code:
while str.find(target,key,n) != -1 and <= len(target):
I get a syntax error on 'less than or equal to sign'. Why?
In English we can say "if X is not equal to Y and also less than Z", but Python syntax doesn't work that way.
If you want to compare a number to two other numbers, you have to repeat the original number in the second comparison.
i.e., instead of this:
if x != y and < z:
you must do this:
if x != y and x < z:
If you want to use the double operand, you could rewrite it like:
if -1 < target.find(key, n) < len(target):
pass
But that said, I don’t think find can ever return a value larger than the length of target.
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).
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.