Python consecutive if statements [duplicate] - python-2.7

Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
Is there a ternary conditional operator in Python?

Yes, it was added in version 2.5. The expression syntax is:
a if condition else b
First condition is evaluated, then exactly one of either a or b is evaluated and returned based on the Boolean value of condition. If condition evaluates to True, then a is evaluated and returned but b is ignored, or else when b is evaluated and returned but a is ignored.
This allows short-circuiting because when condition is true only a is evaluated and b is not evaluated at all, but when condition is false only b is evaluated and a is not evaluated at all.
For example:
>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'
Note that conditionals are an expression, not a statement. This means you can't use statements such as pass, or assignments with = (or "augmented" assignments like +=), within a conditional expression:
>>> pass if False else pass
File "<stdin>", line 1
pass if False else pass
^
SyntaxError: invalid syntax
>>> # Python parses this as `x = (1 if False else y) = 2`
>>> # The `(1 if False else x)` part is actually valid, but
>>> # it can't be on the left-hand side of `=`.
>>> x = 1 if False else y = 2
File "<stdin>", line 1
SyntaxError: cannot assign to conditional expression
>>> # If we parenthesize it instead...
>>> (x = 1) if False else (y = 2)
File "<stdin>", line 1
(x = 1) if False else (y = 2)
^
SyntaxError: invalid syntax
(In 3.8 and above, the := "walrus" operator allows simple assignment of values as an expression, which is then compatible with this syntax. But please don't write code like that; it will quickly become very difficult to understand.)
Similarly, because it is an expression, the else part is mandatory:
# Invalid syntax: we didn't specify what the value should be if the
# condition isn't met. It doesn't matter if we can verify that
# ahead of time.
a if True
You can, however, use conditional expressions to assign a variable like so:
x = a if True else b
Or for example to return a value:
# Of course we should just use the standard library `max`;
# this is just for demonstration purposes.
def my_max(a, b):
return a if a > b else b
Think of the conditional expression as switching between two values. We can use it when we are in a 'one value or another' situation, where we will do the same thing with the result, regardless of whether the condition is met. We use the expression to compute the value, and then do something with it. If you need to do something different depending on the condition, then use a normal if statement instead.
Keep in mind that it's frowned upon by some Pythonistas for several reasons:
The order of the arguments is different from those of the classic condition ? a : b ternary operator from many other languages (such as C, C++, Go, Perl, Ruby, Java, JavaScript, etc.), which may lead to bugs when people unfamiliar with Python's "surprising" behaviour use it (they may reverse the argument order).
Some find it "unwieldy", since it goes contrary to the normal flow of thought (thinking of the condition first and then the effects).
Stylistic reasons. (Although the 'inline if' can be really useful, and make your script more concise, it really does complicate your code)
If you're having trouble remembering the order, then remember that when read aloud, you (almost) say what you mean. For example, x = 4 if b > 8 else 9 is read aloud as x will be 4 if b is greater than 8 otherwise 9.
Official documentation:
Conditional expressions
Is there an equivalent of C’s ”?:” ternary operator?

You can index into a tuple:
(falseValue, trueValue)[test]
test needs to return True or False.
It might be safer to always implement it as:
(falseValue, trueValue)[test == True]
or you can use the built-in bool() to assure a Boolean value:
(falseValue, trueValue)[bool(<expression>)]

For versions prior to 2.5, there's the trick:
[expression] and [on_true] or [on_false]
It can give wrong results when on_true has a false Boolean value.1
Although it does have the benefit of evaluating expressions left to right, which is clearer in my opinion.
1. Is there an equivalent of C’s ”?:” ternary operator?

<expression 1> if <condition> else <expression 2>
a = 1
b = 2
1 if a > b else -1
# Output is -1
1 if a > b else -1 if a < b else 0
# Output is -1

From the documentation:
Conditional expressions (sometimes called a “ternary operator”) have the lowest priority of all Python operations.
The expression x if C else y first evaluates the condition, C (not x); if C is true, x is evaluated and its value is returned; otherwise, y is evaluated and its value is returned.
See PEP 308 for more details about conditional expressions.
New since version 2.5.

An operator for a conditional expression in Python was added in 2006 as part of Python Enhancement Proposal 308. Its form differs from common ?: operator and it looks like this:
<expression1> if <condition> else <expression2>
which is equivalent to:
if <condition>: <expression1> else: <expression2>
Here is an example:
result = x if a > b else y
Another syntax which can be used (compatible with versions before 2.5):
result = (lambda:y, lambda:x)[a > b]()
where operands are lazily evaluated.
Another way is by indexing a tuple (which isn't consistent with the conditional operator of most other languages):
result = (y, x)[a > b]
or explicitly constructed dictionary:
result = {True: x, False: y}[a > b]
Another (less reliable), but simpler method is to use and and or operators:
result = (a > b) and x or y
however this won't work if x would be False.
A possible workaround is to make x and y lists or tuples as in the following:
result = ((a > b) and [x] or [y])[0]
or:
result = ((a > b) and (x,) or (y,))[0]
If you're working with dictionaries, instead of using a ternary conditional, you can take advantage of get(key, default), for example:
shell = os.environ.get('SHELL', "/bin/sh")
Source: ?: in Python at Wikipedia

Unfortunately, the
(falseValue, trueValue)[test]
solution doesn't have short-circuit behaviour; thus both falseValue and trueValue are evaluated regardless of the condition. This could be suboptimal or even buggy (i.e. both trueValue and falseValue could be methods and have side effects).
One solution to this would be
(lambda: falseValue, lambda: trueValue)[test]()
(execution delayed until the winner is known ;)), but it introduces inconsistency between callable and non-callable objects. In addition, it doesn't solve the case when using properties.
And so the story goes - choosing between three mentioned solutions is a trade-off between having the short-circuit feature, using at least Python 2.5 (IMHO, not a problem anymore) and not being prone to "trueValue-evaluates-to-false" errors.

Ternary operator in different programming languages
Here I just try to show some important differences in the ternary operator between a couple of programming languages.
Ternary operator in JavaScript
var a = true ? 1 : 0;
# 1
var b = false ? 1 : 0;
# 0
Ternary operator in Ruby
a = true ? 1 : 0
# 1
b = false ? 1 : 0
# 0
Ternary operator in Scala
val a = true ? 1 | 0
# 1
val b = false ? 1 | 0
# 0
Ternary operator in R programming
a <- if (TRUE) 1 else 0
# 1
b <- if (FALSE) 1 else 0
# 0
Ternary operator in Python
a = 1 if True else 0
# 1
b = 1 if False else 0
# 0

For Python 2.5 and newer there is a specific syntax:
[on_true] if [cond] else [on_false]
In older Pythons, a ternary operator is not implemented but it's possible to simulate it.
cond and on_true or on_false
Though there is a potential problem, which is if cond evaluates to True and on_true evaluates to False then on_false is returned instead of on_true. If you want this behaviour the method is OK, otherwise use this:
{True: on_true, False: on_false}[cond is True] # is True, not == True
which can be wrapped by:
def q(cond, on_true, on_false)
return {True: on_true, False: on_false}[cond is True]
and used this way:
q(cond, on_true, on_false)
It is compatible with all Python versions.

You might often find
cond and on_true or on_false
but this leads to a problem when on_true == 0
>>> x = 0
>>> print x == 0 and 0 or 1
1
>>> x = 1
>>> print x == 0 and 0 or 1
1
Where you would expect this result for a normal ternary operator:
>>> x = 0
>>> print 0 if x == 0 else 1
0
>>> x = 1
>>> print 0 if x == 0 else 1
1

Does Python have a ternary conditional operator?
Yes. From the grammar file:
test: or_test ['if' or_test 'else' test] | lambdef
The part of interest is:
or_test ['if' or_test 'else' test]
So, a ternary conditional operation is of the form:
expression1 if expression2 else expression3
expression3 will be lazily evaluated (that is, evaluated only if expression2 is false in a boolean context). And because of the recursive definition, you can chain them indefinitely (though it may considered bad style.)
expression1 if expression2 else expression3 if expression4 else expression5 # and so on
A note on usage:
Note that every if must be followed with an else. People learning list comprehensions and generator expressions may find this to be a difficult lesson to learn - the following will not work, as Python expects a third expression for an else:
[expression1 if expression2 for element in iterable]
# ^-- need an else here
which raises a SyntaxError: invalid syntax.
So the above is either an incomplete piece of logic (perhaps the user expects a no-op in the false condition) or what may be intended is to use expression2 as a filter - notes that the following is legal Python:
[expression1 for element in iterable if expression2]
expression2 works as a filter for the list comprehension, and is not a ternary conditional operator.
Alternative syntax for a more narrow case:
You may find it somewhat painful to write the following:
expression1 if expression1 else expression2
expression1 will have to be evaluated twice with the above usage. It can limit redundancy if it is simply a local variable. However, a common and performant Pythonic idiom for this use-case is to use or's shortcutting behavior:
expression1 or expression2
which is equivalent in semantics. Note that some style-guides may limit this usage on the grounds of clarity - it does pack a lot of meaning into very little syntax.

One of the alternatives to Python's conditional expression
"yes" if boolean else "no"
is the following:
{True: "yes", False: "no"}[boolean]
which has the following nice extension:
{True: "yes", False: "no", None: "maybe"}[boolean_or_none]
The shortest alternative remains
("no", "yes")[boolean]
which works because issubclass(bool, int).
Careful, though: the alternative to
yes() if boolean else no()
is not
(no(), yes())[boolean] # bad: BOTH no() and yes() are called
but
(no, yes)[boolean]()
This works fine as long as no and yes are to be called with exactly the same parameters. If they are not, like in
yes("ok") if boolean else no() # (1)
or in
yes("ok") if boolean else no("sorry") # (2)
then a similar alternative either does not exist (1) or is hardly viable (2). (In rare cases, depending on the context, something like
msg = ("sorry", "ok")[boolean]
(no, yes)[boolean](msg)
could make sense.)
Thanks to Radek Rojík for his comment

As already answered, yes, there is a ternary operator in Python:
<expression 1> if <condition> else <expression 2>
In many cases <expression 1> is also used as Boolean evaluated <condition>. Then you can use short-circuit evaluation.
a = 0
b = 1
# Instead of this:
x = a if a else b
# Evaluates as 'a if bool(a) else b'
# You could use short-circuit evaluation:
x = a or b
One big pro of short-circuit evaluation is the possibility of chaining more than two expressions:
x = a or b or c or d or e
When working with functions it is more different in detail:
# Evaluating functions:
def foo(x):
print('foo executed')
return x
def bar(y):
print('bar executed')
return y
def blubb(z):
print('blubb executed')
return z
# Ternary Operator expression 1 equals to False
print(foo(0) if foo(0) else bar(1))
''' foo and bar are executed once
foo executed
bar executed
1
'''
# Ternary Operator expression 1 equals to True
print(foo(2) if foo(2) else bar(3))
''' foo is executed twice!
foo executed
foo executed
2
'''
# Short-circuit evaluation second equals to True
print(foo(0) or bar(1) or blubb(2))
''' blubb is not executed
foo executed
bar executed
1
'''
# Short-circuit evaluation third equals to True
print(foo(0) or bar(0) or blubb(2))
'''
foo executed
bar executed
blubb executed
2
'''
# Short-circuit evaluation all equal to False
print(foo(0) or bar(0) or blubb(0))
''' Result is 0 (from blubb(0)) because no value equals to True
foo executed
bar executed
blubb executed
0
'''
PS: Of course, a short-circuit evaluation is not a ternary operator, but often the ternary is used in cases where the short circuit would be enough. It has a better readability and can be chained.

Simulating the Python ternary operator.
For example
a, b, x, y = 1, 2, 'a greather than b', 'b greater than a'
result = (lambda:y, lambda:x)[a > b]()
Output:
'b greater than a'

a if condition else b
Just memorize this pyramid if you have trouble remembering:
condition
if else
a b

The ternary conditional operator simply allows testing a condition in a single line replacing the multiline if-else making the code compact.
Syntax:
[on_true] if [expression] else [on_false]
1- Simple Method to use ternary operator:
# Program to demonstrate conditional operator
a, b = 10, 20
# Copy value of a in min if a < b else copy b
min = a if a < b else b
print(min) # Output: 10
2- Direct Method of using tuples, Dictionary, and lambda:
# Python program to demonstrate ternary operator
a, b = 10, 20
# Use tuple for selecting an item
print( (b, a) [a < b] )
# Use Dictionary for selecting an item
print({True: a, False: b} [a < b])
# lambda is more efficient than above two methods
# because in lambda we are assure that
# only one expression will be evaluated unlike in
# tuple and Dictionary
print((lambda: b, lambda: a)[a < b]()) # in output you should see three 10
3- Ternary operator can be written as nested if-else:
# Python program to demonstrate nested ternary operator
a, b = 10, 20
print ("Both a and b are equal" if a == b else "a is greater than b"
if a > b else "b is greater than a")
Above approach can be written as:
# Python program to demonstrate nested ternary operator
a, b = 10, 20
if a != b:
if a > b:
print("a is greater than b")
else:
print("b is greater than a")
else:
print("Both a and b are equal")
# Output: b is greater than a

Vinko Vrsalovic's answer is good enough. There is only one more thing:
Note that conditionals are an expression, not a statement. This means you can't use assignment statements or pass or other statements within a conditional expression
Walrus operator in Python 3.8
After the walrus operator was introduced in Python 3.8, something changed.
(a := 3) if True else (b := 5)
gives a = 3 and b is not defined,
(a := 3) if False else (b := 5)
gives a is not defined and b = 5, and
c = (a := 3) if False else (b := 5)
gives c = 5, a is not defined and b = 5.
Even if this may be ugly, assignments can be done inside conditional expressions after Python 3.8. Anyway, it is still better to use normal if statement instead in this case.

More a tip than an answer (I don't need to repeat the obvious for the hundredth time), but I sometimes use it as a one-liner shortcut in such constructs:
if conditionX:
print('yes')
else:
print('nah')
, becomes:
print('yes') if conditionX else print('nah')
Some (many :) may frown upon it as unpythonic (even, Ruby-ish :), but I personally find it more natural - i.e., how you'd express it normally, plus a bit more visually appealing in large blocks of code.

You can do this:
[condition] and [expression_1] or [expression_2];
Example:
print(number%2 and "odd" or "even")
This would print "odd" if the number is odd or "even" if the number is even.
The result: If condition is true, exp_1 is executed, else exp_2 is executed.
Note: 0, None, False, emptylist, and emptyString evaluates as False.
And any data other than 0 evaluates to True.
Here's how it works:
If the condition [condition] becomes "True", then expression_1 will be evaluated, but not expression_2.
If we "and" something with 0 (zero), the result will always to be false. So in the below statement,
0 and exp
The expression exp won't be evaluated at all since "and" with 0 will always evaluate to zero and there is no need to evaluate the expression. This is how the compiler itself works, in all languages.
In
1 or exp
the expression exp won't be evaluated at all since "or" with 1 will always be 1. So it won't bother to evaluate the expression exp since the result will be 1 anyway (compiler optimization methods).
But in case of
True and exp1 or exp2
The second expression exp2 won't be evaluated since True and exp1 would be True when exp1 isn't false.
Similarly in
False and exp1 or exp2
The expression exp1 won't be evaluated since False is equivalent to writing 0 and doing "and" with 0 would be 0 itself, but after exp1 since "or" is used, it will evaluate the expression exp2 after "or".
Note:- This kind of branching using "or" and "and" can only be used when the expression_1 doesn't have a Truth value of False (or 0 or None or emptylist [ ] or emptystring ' '.) since if expression_1 becomes False, then the expression_2 will be evaluated because of the presence "or" between exp_1 and exp_2.
In case you still want to make it work for all the cases regardless of what exp_1 and exp_2 truth values are, do this:
[condition] and ([expression_1] or 1) or [expression_2];

Many programming languages derived from C usually have the following syntax of the ternary conditional operator:
<condition> ? <expression1> : <expression2>
At first, the Python's benevolent dictator for life (I mean Guido van Rossum, of course) rejected it (as non-Pythonic style), since it's quite hard to understand for people not used to C language. Also, the colon sign : already has many uses in Python. After PEP 308 was approved, Python finally received its own shortcut conditional expression (what we use now):
<expression1> if <condition> else <expression2>
So, firstly it evaluates the condition. If it returns True, expression1 will be evaluated to give the result, otherwise expression2 will be evaluated. Due to lazy evaluation mechanics – only one expression will be executed.
Here are some examples (conditions will be evaluated from left to right):
pressure = 10
print('High' if pressure < 20 else 'Critical')
# Result is 'High'
Ternary operators can be chained in series:
pressure = 5
print('Normal' if pressure < 10 else 'High' if pressure < 20 else 'Critical')
# Result is 'Normal'
The following one is the same as previous one:
pressure = 5
if pressure < 20:
if pressure < 10:
print('Normal')
else:
print('High')
else:
print('Critical')
# Result is 'Normal'

Yes, Python have a ternary operator, here is the syntax and an example code to demonstrate the same :)
#[On true] if [expression] else[On false]
# if the expression evaluates to true then it will pass On true otherwise On false
a = input("Enter the First Number ")
b = input("Enter the Second Number ")
print("A is Bigger") if a>b else print("B is Bigger")

Other answers correctly talk about the Python ternary operator. I would like to complement by mentioning a scenario for which the ternary operator is often used, but for which there is a better idiom. This is the scenario of using a default value.
Suppose we want to use option_value with a default value if it is not set:
run_algorithm(option_value if option_value is not None else 10)
or, if option_value is never set to a falsy value (0, "", etc.), simply
run_algorithm(option_value if option_value else 10)
However, in this case an ever better solution is simply to write
run_algorithm(option_value or 10)

The syntax for the ternary operator in Python is:
[on_true] if [expression] else [on_false]
Using that syntax, here is how we would rewrite the code above using Python’s ternary operator:
game_type = 'home'
shirt = 'white' if game_type == 'home' else 'green'
It's still pretty clear, but much shorter. Note that the expression could be any type of expression, including a function call, that returns a value that evaluates to True or False.

Python has a ternary form for assignments; however there may be even a shorter form that people should be aware of.
It's very common to need to assign to a variable one value or another depending on a condition.
>>> li1 = None
>>> li2 = [1, 2, 3]
>>>
>>> if li1:
... a = li1
... else:
... a = li2
...
>>> a
[1, 2, 3]
^ This is the long form for doing such assignments.
Below is the ternary form. But this isn't the most succinct way - see the last example.
>>> a = li1 if li1 else li2
>>>
>>> a
[1, 2, 3]
>>>
With Python, you can simply use or for alternative assignments.
>>> a = li1 or li2
>>>
>>> a
[1, 2, 3]
>>>
The above works since li1 is None and the interpreter treats that as False in logic expressions. The interpreter then moves on and evaluates the second expression, which is not None and it's not an empty list - so it gets assigned to a.
This also works with empty lists. For instance, if you want to assign a whichever list has items.
>>> li1 = []
>>> li2 = [1, 2, 3]
>>>
>>> a = li1 or li2
>>>
>>> a
[1, 2, 3]
>>>
Knowing this, you can simply such assignments whenever you encounter them. This also works with strings and other iterables. You could assign a whichever string isn't empty.
>>> s1 = ''
>>> s2 = 'hello world'
>>>
>>> a = s1 or s2
>>>
>>> a
'hello world'
>>>
I always liked the C ternary syntax, but Python takes it a step further!
I understand that some may say this isn't a good stylistic choice, because it relies on mechanics that aren't immediately apparent to all developers. I personally disagree with that viewpoint. Python is a syntax-rich language with lots of idiomatic tricks that aren't immediately apparent to the dabbler. But the more you learn and understand the mechanics of the underlying system, the more you appreciate it.

Pythonic way of doing the things:
"true" if var else "false"
But there always exists a different way of doing a ternary condition too:
"true" and var or "false"

There are multiple ways. The simplest one is to use the condition inside the "print" method.
You can use
print("Twenty" if number == 20 else "Not twenty")
Which is equivalent to:
if number == 20:
print("Twenty")
else:
print("Not twenty")
In this way, more than two statements are also possible to print. For example:
if number == 20:
print("Twenty")
elif number < 20:
print("Lesser")
elif 30 > number > 20:
print("Between")
else:
print("Greater")
can be written as:
print("Twenty" if number == 20 else "Lesser" if number < 20 else "Between" if 30 > number > 20 else "Greater")

The if else-if version can be written as:
sample_set="train" if "Train" in full_path else ("test" if "Test" in full_path else "validation")

Yes, it has, but it's different from C-syntax-like programming languages (which is condition ? value_if_true : value_if_false
In Python, it goes like this: value_if_true if condition else value_if_false
Example: even_or_odd = "even" if x % 2 == 0 else "odd"

A neat way to chain multiple operators:
f = lambda x,y: 'greater' if x > y else 'less' if y > x else 'equal'
array = [(0,0),(0,1),(1,0),(1,1)]
for a in array:
x, y = a[0], a[1]
print(f(x,y))
# Output is:
# equal,
# less,
# greater,
# equal

I find the default Python syntax val = a if cond else b cumbersome, so sometimes I do this:
iif = lambda (cond, a, b): a if cond else b
# So I can then use it like:
val = iif(cond, a, b)
Of course, it has the downside of always evaluating both sides (a and b), but the syntax is way clearer to me.

Related

Error when using ismatch() function with regex in Julia

I'm trying to do a very simple program to find matches with ismatch() function in Julia. Suppose my pattern is
e_pat = r".+#.+"
Then I make a list called input with some random elements:
input= ["pipo#gmail.com", 23, "trapo", "holi#gmail.com"]
Now I want to identify how many matches exist and then print them using e_pat as reference:
for i in input
println(ismatch(e_pat, i)) && println(i)
end
With that code I just get "true" and the error displayed below:
true
TypeError: non-boolean (Void) used in boolean context
Stacktrace:
[1] macro expansion at ./In[27]:4 [inlined]
[2] anonymous at ./<missing>:?
[3] include_string(::String, ::String) at ./loading.jl:522
What can I do in order to get the following?
"pipo#gmail.com"
"holi#gmail.com"
I read ismatch() documentation but found nothing useful.
Any help will be much appreciated
The problem is that while this expression returns true:
julia> #show ismatch(e_pat, "pipo#gmail.com");
ismatch(e_pat,"pipo#gmail.com") = true
Using println, just prints true but returns nothing:
julia> #show println(ismatch(e_pat, "pipo#gmail.com"));
true
println(ismatch(e_pat,"pipo#gmail.com")) = nothing
Which is of type Void:
julia> typeof(nothing)
Void
And the error is telling you that you cant use an object of type Void in a boolean context (nothing) is just an instance of Void treated like a singleton in Julia:
julia> nothing && true
ERROR: TypeError: non-boolean (Void) used in boolean context
After fixing that also notice that this is also another error:
julia> #show ismatch(e_pat, 42);
ERROR: MethodError: no method matching ismatch(::Regex, ::Int32)
Closest candidates are:
ismatch(::Regex, ::SubString{T<:AbstractString}) at regex.jl:151
ismatch(::Regex, ::SubString{T<:AbstractString}, ::Integer) at regex.jl:151
ismatch(::Regex, ::AbstractString) at regex.jl:145
...
This is telling you that ismatch has no such method, you can't use it with a combination of arguments of types: (Regex, Int).
You could do something like this instead to make sure all the objects are Strings:
julia> input = string.(["pipo#gmail.com", 23, "trapo", "holi#gmail.com"])
4-element Array{String,1}:
"pipo#gmail.com"
"23"
"trapo"
"holi#gmail.com"
Finally, you could use the macro #show (which prints an expression and its result and finally returns the result) instead of the println function (which prints the result and returns nothing, to debug whats going on:
julia> for i in input
#show(ismatch(e_pat, i)) && println(i)
end
ismatch(e_pat,i) = true
pipo#gmail.com
ismatch(e_pat,i) = false
ismatch(e_pat,i) = false
ismatch(e_pat,i) = true
holi#gmail.com
So in order to print your expected result just remove the left hand side println:
julia> for i in input
ismatch(e_pat, i) && println(i)
end
pipo#gmail.com
holi#gmail.com
If you want to store them instead of printing them you could us an array comprehension instead:
julia> result = [str for str in input if ismatch(e_pat, str)]
2-element Array{String,1}:
"pipo#gmail.com"
"holi#gmail.com"
Or an indexing expression like this one:
julia> ismatch.(e_pat, input)
4-element BitArray{1}:
true
false
false
true
julia> result = input[ismatch.(e_pat, input)]
2-element Array{String,1}:
"pipo#gmail.com"
"holi#gmail.com"
That way you could print them later without having to repeat the computation:
julia> println.(result)
pipo#gmail.com
holi#gmail.com

how multiple OR's and AND evaluate

This is very simple question, but I can't get it. I have simple condition:
bool c = true || true || true && false;
Why this evaluation is true? As far as I know it evaluates like this:
true || true || true && false => true || true && false => true && false => false
But guess im wrong.
You just have to learn some few basic rules:
(a OR b) is true IF AND ONLY IF at least one of a or b is true.
(a AND b) is true IF AND ONLY IF both of a and b are true.
ORDER of Operators MATTERS: you can't just do the logic any way that you want. computer calculates the output of the a logical statement by an order. a simplified order is like this: First is Grouping (), Second is And, Third is OR.
so when you say bool c = true || true || true && false;. the computer says ok let's first calculate true && false. it is false! and then it calculates true || true || false which is true.
EDIT
Note 1: a complete list of logical operators and their precedence is heavily dependent on the language. you can refer to the documentation for that.
for C#
Note 2: the best practice is to use GROUPING like parenthesis because GROUPING is always of priority. for example it's better to say:
bool c = (true || true) || (true && false);
Think of OR || like addition and AND && as multiplication. There is a priority in there, in fact, you will sometimes see them written as such:
bool c = true + true + true + true * false
In this case, the first evaluation is true * false, then the rest of the ORs. In this particular case, the true order of evaluation of the ORs will depend on language/compiler.
If you want to force a particular order, you can always use parentheses.

python tuple comparison, 'less than' revisited (2.7)

I want to understand Python's behavior for tuple comparison operators, specifically < (the less-than operator).
edit: Now I get it, thank you Jaroslaw for a clear answer.
My error was thinking 1) "Lexicographical comparison" was a synonym for "string compare",
and 2) thinking that the "string compare logic" applied to each element of the tuples being compared instead of at the tuple-level. Which yields valid behavior for == but not so much for <.
On the off chance anyone else gets stuck on the distinction.
excerpt from wikipedia (emphasis added)4: ...lexicographical order ... is a generalization
of the way the alphabetical order of words is based on the alphabetical order of their component letters.
This generalization consists primarily in defining a total order over the sequences ... of
elements of a finite totally ordered set, often called alphabet.
original question text follows...
Wait, you say, hasn't this been asked before?
Yes... and pretty well answered for == (equality).
I want to understand why ( 1, 2 ) < ( 1, 3 ) yields True (note the < less than operator, code example below). This is likely just a python-newbie error on my part, but I am having trouble finding it.
I've read some other questions about how tuple comparisons involves "lexicographic comparisons of the respective elements form each tuple."
Question: python-tuple-comparison-odd-behavior: This question is about using the in operator, I'm interested in < (less than), not so much the behavior of in (at least not yet).
Question: python-tuple-comparison: For this one the answer says (emphasis added):
excerpt from Answer: Tuples are compared position by position: the first item of first
tuple is compared to the first item of the second tuple; if they are
not equal, this is the result of the comparison, else the second item
is considered, then the third and so on.
Which I understand for == comparisons.
edit: *thought I understood
To generalize to all comparison operators I would modify the answer to be something like this:
... the first item of first tuple is compared to the
first item of the second tuple; if the comaprison yields False
then the result of the tuple comaprison is also False. Otherwise
the comparison continues with the remaining items....
edit: this was wrong. Subtly wrong though, worked for == but not other relational operators.
I am having trouble seeing how that works for < (less than) comparisons.
The python documentation they link to (modified to point to 2.7) also talks about this in terms of equality, not less than - again, emphasis added:
excerpt from python docs: Sequence types also support comparisons. In particular, tuples and
lists are compared lexicographically by comparing corresponding
elements. This means that to compare equal, every element must compare
equal and the two sequences must be of the same type and have the same
length. (For full details see Comparisons in the language reference.)
edit: at this point when writing up my original question I had tunnel vision on 'equality'.
I found nothing helpful in the The Comparisons language reference; it doesn't touch on why ( 1, 2 ) < ( 1, 3 ) yields True when the comparison operator seems like it should yield False for the first pair of elements.
The following is some example output of a toy test program; most of it works as I would expect. Please note the 2 embedded questions.
Ouput from "tcomp.py" (source below).
$ python tcomp.py
tcomp.py
version= 2.7.12
--- empty tuples, intuitive, no surprises ---
() == () : True
() < () : False
() > () : False
--- single-item tuples, equal values: intuitive, no surprises ---
(1,) == (1,) : True
(1,) < (1,) : False
(1,) > (1,) : False
--- single-item diff: intuitive, no surprises ---
(1,) == (2,) : False
(1,) < (2,) : True
(1,) > (2,) : False
--- double-item same: intuitive, no surprises ---
(1, 2) == (1, 2) : True
(1, 2) < (1, 2) : False
(1, 2) > (1, 2) : False
* Question: do a<b and a>b both yield False
* because Python short circuits on
* a[0] < b[0] (and correspondingly a[0] > b[0] )?
* e.g. Python never bothers comparing second
* elements: a[1] < b[1] (and, correspondinlgy, a[1] > b[1] ).
--- double-item 1st=same 2nd=diff: ??? What is with a<b ???
(1, 2) == (1, 3) : False
(1, 2) < (1, 3) : True
(1, 2) > (1, 3) : False
* Question: Here I get the == comparison, that yields False like I would expect.
* But WHAT is going on with the < comparison?
* Even comapring "lexicographically", how does a[0] < b[0]
* actually yield True ?
* Is Python really comparing a[0] < b[0] ?
* Because in my mental model that is the same as comparing: 1 < 1
* I kind of think 1 < 1 is supposed to be False, even if Python
* is comparing "1" < "1" (e.g. lexicographically).
$
To add to the last "*Question" above, comapring a[0] < b[0] lexicographically would be like comparing '1' < '1' which still should be false, yes?
tcomp.py:
import platform
def tupleInfo( a, b, msg ):
# using labels instead of eval-style stuff to keep things simpler.
print
print '--- ' , msg , ' ---'
print a, ' == ', b, ' : ', a == b
print a, ' < ', b, ' : ', a < b
print a, ' > ', b, ' : ', a > b
print 'tcomp.py'
print 'version=', platform.python_version()
# let's start with some empty tuples.
e1 = tuple()
e2 = tuple()
tupleInfo( tuple( ) , tuple( ) , 'empty tuples,intuitive, no surprises' )
tupleInfo( tuple( [ 1 ] ) , tuple( [ 1 ] ) , 'single-item tuples, equal values: intuitive, no surprises' )
tupleInfo( tuple( [ 1 ] ) , tuple( [ 2 ] ) , 'single-item diff: intuitive, no surprises' )
tupleInfo( tuple( [ 1, 2 ] ), tuple( [ 1, 2 ] ), 'double-item same: intuitive, no surprises' )
print '* Question: do a<b and a>b both yield False '
print '* because Python short circuits on'
print '* a[0] < b[0] (and correspondingly a[0] > b[0] )?'
print '* e.g. Python never bothers comparing second'
print '* elements: a[1] < b[1] (and, correspondinlgy, a[1] > b[1] ).'
tupleInfo( tuple( [ 1, 2 ] ), tuple( [ 1, 3 ] ), 'double-item 1st=same 2nd=diff: ??? What is with a<b ???' )
print '* Question: Here I get the == comparison, that yields False like I would expect.'
print '* But WHAT is going on with the < comparison?'
print '* Even comapring "lexicographically", how does a[0] < b[0]'
print '* actually yield True ?'
print '* Is Python really comparing a[0] < b[0] ?'
print '* Because in my mental model that is the same as comparing: 1 < 1'
print '* I kind of think 1 < 1 is supposed to be False, even if Python'
print '* is comparing "1" < "1" (e.g. lexicographically).'
The answer lies in word 'lexigographicly'. It means, that python compares tuples beginning from the first position. This order is used in vocabularies or lexicons - word a is smaller than word b, if a apperars in vocabulary before b. Then we can compare two words like 'anthrax' and 'antipodes', where three first letters are equal: 'anthrax' appears in vocabulary before 'antipodes', so the statement 'anthrax' < 'antipodes' is True.
This comparision can be represented like this:
def isSmaller(a, b): # returns true if a<b, false if a>=b
for i in xrange(0, a.__len__()): # for every elementof a, starting from left
if b.__len__() <= i: # if a starts with b, but a is longer, eg. b='ab', a='ab...'
return False
if a[i] < b[i]: # if a starts like b, but there is difference on i-th position,
# eg. a='abb...', b='abc...',
return True
if a[i] > b[i]: # eg. a='abc...', b='abb...',
return False
if a[i] == b[i]: # if there is no difference, check the next position
pass
if a.__len__() < b.__len__(): # if b starts with a, but b is longer, eg. a='ac', b='ac...'
return True
else: # else, ie. when a is the same as b, eg. a='acdc', b='acdc'
return False
print (1,2,3)<(1,2)
print (1,2,3)<(1,2,3)
print (1,2,3)<(1,3,2)
print isSmaller((1,2,3),(1,2))
print isSmaller((1,2,3),(1,2,3))
print isSmaller((1,2,3),(1,3,2))
Output:
False
False
True
False
False
True

Ternary operator in Python raises TypeError when using * operator on empty list?

I want to print the contents of a list a if len(a) > 0, but otherwise I want to print -1. This seems to be pretty simple, but it's raising a TypeError, stating that a is an int, not a sequence, only when a is an empty list:
>>> a = [2]
>>> print(*a if len(a) > 0 else -1)
2 # as expected
>>> a = []
>>> print(*a)
>>> # It has no trouble evaluating *a when a is empty
... ### HERE IS THE ERROR:
...
>>> print(*a if len(a) > 0 else -1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: print() argument after * must be a sequence, not int
>>> ### But this works fine:
...
>>> if len(a) > 0:
... print(*a)
... else:
... print(-1)
...
-1
Why is this the case?
According to the Python Documentation:
The expression x if C else y first evaluates the condition, C rather
than x. If C is true, x is evaluated and its value is returned;
otherwise, y is evaluated and its value is returned.
So *a shouldn't be getting evaluated at all, and yet it's causing a TypeError?
I'm using Python 3.5
I'm not an expert, but looking at PEP 448 it looks like this * syntax isn't part of the general expression syntax, but it's specific to function callsites (and other things like tuple and dictionary displays). (It's a bit of a hack.)
The PEP explicitly calls out some similar syntax that they've forbidden because they didn't know what it should do. It doesn't look like your code has been particularly considered though.
Unbracketed comprehensions in function calls, such as f(x for x in it), are already valid. These could be extended to:
f(*x for x in it) == f((*x for x in it))
f(**x for x in it) == f({**x for x in it})
However, it wasn't clear if this was the best behaviour
or if it should unpack into the arguments of the call to f. Since
this is likely to be confusing and is of only very marginal utility,
it is not included in this PEP. Instead, these will throw a
SyntaxError and comprehensions with explicit brackets should be used
instead.
I think your code is effectively parsing as print(*(a if len(a) > 0 else -1)), which is why you then get the error TypeError: print() argument after * must be a sequence, not int. By comparison, this works:
>>> print(*a if len(a) > 0 else ['nothing'])
nothing

In Lua what does an if statement with only one argument mean?

I've been taught to program in Java. Lua is new to me and I've tried to do my homework but am not sure what an if statement of the following nature means.
The code is as follows:
local function getMinHeight(self)
local minHeight = 0
for i=1, minimizedLines do
local line = select(9+i, self:GetRegions())
**if(line) then
minHeight = minHeight + line:GetHeight() + 2.5
end**
end
if(minHeight == 0) then
minHeight = select(2, self:GetFont()) + 2.5
end
return minHeight
end
The if statement with the ** before and after is the part I'm not sure about. I don't know what the if statement is checking. If the line is not nil? If the line exists? If what?
In Lua, anything that's not nil or false evaluates to true in a conditional.
If the line is not nil? If the line exists?
Yes to both, because they kinda mean the same thing.
The select function returns a specific argument from it's list of arguments. It's used primarily with ..., but in this case it's being used to select the (i+9)th value returned by self:GetRegions. If there is no such value (for instance, if GetRegions only returns 5 values), then select returns nil.
if(line) is checking to see that it got a value back from select.
if(line) is being used as a shortcut for if(line ~= nil), since nil evaluates to false in a conditional.
It's worth pointing out that this shortcut is not always appropriate. For instance, we can iterate all the values in a table like this:
key, val = next(lookup)
while key do
print(key, val)
key, val = next(lookup, key)
end
However, this will fail if one of the table's keys happens be false:
lookup = {
["fred"] = "Fred Flinstone",
[true] = "True",
[false] = "False",
}
So we have to explicitly check for nil:
key, val = next(lookup)
while key ~= nil do
print(key, val)
key, val = next(lookup, key)
end
As Mud says, in lua anything other than nil and false is considered truthy. So the if above will pass as long as line is not nil or false.
That said, it worries me a bit the way you have phrased the question - "an if with only one argument".
First, it's not called "argument" - it's called expression. And in most languages is always one. In java, for example, you could do something like this:
bool found = false
...
if(found) {
...
}
ifs only care about the final value of the expression; they don't care whether it's a single variable or a more complex construction.