Python ternary_operator (do-somthing if flag else do-another) - python

Is there method by using python if/else (ternary_operator) to achieve this function:
flag = True # or False
if flag:
print 'abc'
else:
pass
I tried to using:
print 'abc' if flag else ''
But a blank line will be print if the flag == False. Because:
print 'abc' if flag else '' == print ('abc' if flag else '')
Is there any way can make print nothing if flag == False without using ;?
Thanks in advance.
By the way, I'v tried using lambda, but it wasn't successful, here my code:
a = lambda x: x if False else None
print a(1)
Result:
>> python a.py
None

In Python 2.X print is a statement while in 3.X print is a function.
You can do from __future__ import print_function and print will now be a function. You can then do print("abc") if condition else None if you want to print in an expression. Note that the value of the expression is always None, but it may or may not print "abc" depending on the value of condition.
You may want to reconsider your programming style. It can be confusing with side-effects, like printing, happening in expressions. Furthermore, Python isn't ideal for functional programming, in my opinion, for a number of reasons. For example:
There are no proper tail calls so you would easily get stack overflows (or max recursion depth errors).
You cannot have statements in lambda-expressions. This includes yield statements that otherwise could be used to mitigate the lack of tail calls.

Why not just:
if flag:
print "abc"
else:
# do something else
?

from __future__ import print_function
print('abc') if flag else None

Related

Python equivalent of omitting second part of ternary operator (a if a else b)

In some languages (I think php and Java) you can omit the second part of the ternary operator as such:
a = "This is a string"
result = a ? : False
The above should be equivalent to
a = "This is a string"
result = a ? a : False
I want to shorten the ternary operator in the following (simplified) python code:
def myFunc():
return "This string could be empty, but now it's not."
result = myFunc() if myFunc() else False
print(result)
This will print the string if it's not empty, but print False when it is empty.
The reason why I want it shorter is because now, I have to call myFunc() two times instead of just once if you were able to omit one of them as is possible in other languages.
Of course I could just assign myFunc() to a variable and use the variable twice in the ternary operator but this would make it bigger again.
Is there any easy way to do this in python? Or is this just not possible?
You can use or here as an empty string evaluates as a Falsey value:
result = myFunc() or False
Refer to Truth Value Testing

Why "if-else-break" breaks in python?

I am trying to use if-else expression which is supposed to break the loop if the if condition fails, but getting an invalid syntax error.
Sample code:
a = 5
while True:
print(a) if a > 0 else break
a-=1
Of course, if I write in the traditional way (not using the one liner) it works.
What is wrong in using the break command after the else keyword?
If I run this, I get the following error:
... print(a) if a > 0 else break
File "<stdin>", line 2
print(a) if a > 0 else break
^
SyntaxError: invalid syntax
This is because
print(a) if a > 5 else break
is a ternary operator. Ternary operators are no if statements. These work with syntax:
<expr1> if <expr2> else <expr3>
It is equivalent to a "virtual function":
def f():
if <expr2>:
return <expr1>
else:
return <expr3>
So that means the part next to the else should be an expression. break is not an expression, it is a statement. So Python does not expect that. You can not return a break.
In python-2.x, print was not a function either. So this would error with the print statement. In python-2.x print was a keyword.
You can rewrite your code to:
a = 5
while True:
if a > 5:
print(a)
else:
break
a -= 1
You can read more about this in the documentation and PEP-308.
If is an expression, break similar to return is a statement. You can't use two statements in a single sentence (unless you use a semicolon which is ugly). I know it would have been really cool if we can do that, but alas that's the way it is.
To put it in slightly simpler terms, you're misusing the 'one-line if statement' (ternary operator). It always evaluates to an expression (i.e., a value). That is,
<expr1> if <condition> else <expr2>
evaluates to <expr1> if <condition> is True, and to <expr2> if <condition> is False. This resulting value can then be used like any Python value, for example:
y = 0
x = (5 if (y > 0) else 6)
print(x) # 6
Of course, the parentheses are completely unnecessary (even discouraged), but hopefully are useful for understanding the meaning of that line.
Therefore,
print(a) if a > 0 else break
tries to evaluate print(a) (which, by the definition of print() in Python 3, always returns None – perfectly valid, but probably not what you usually want) and then break, which does not evaluate to anything because it is a statement (action), not an expression (value), hence the invalid syntax error.
Hence, if you want to execute one of two statements depending on a condition, you really need the multi-line solution proposed by
Willem Van Onsem. There may be hacky ways to do it in one line, but multiple lines is the usual solution for something like this in Python.

Function that checks if a string occurs in another string

I'm currently reading and doing each and every of the exercises in John Guttag's Introduction to Computation and Programming Using Python. One particular problem I cannot solve for the life of me:
Write a function isIn that accepts two strings as arguments and
returns True if either string occurs anywhere in the other, and False
otherwise. Hint: you might want to use the built-in str operation in.
I went through every discussion I could find here, tried with both in and find, constantly changing something in the code, but every time I would run my program to check if 'abc' occurs in 'efg' the answer would be True.
Any idea how to solve it? Again, I need to write a function, not simply go with in like:
x='abc'
y='efg'
if x in y:
# Blah
else:
# another Blah
The code I wrote (I'm adding this as apparently some would like to see it) was basically this:
def isIn(x,y):
if x in y or y in x:
return True
else:
return False
a='abc'
b='efg'
isIn(a,b)
if True:
print "True"
else:
print "False"
The problem is that you are completely ignoring the return value of the function isIn, and the reason why you always get True printed by the code is that the condition you are checking in the if statement is the boolean constant True, which is of course always True.
Try changing your code to:
a='abc'
b='efg'
r = isIn(a,b)
if r:
print "True"
else:
print "False"
Simply put:
x=input('Enter string #1: ')
y=input('Enter string #2: ')
#can also just define x and y separately in the console and invoke the
# function on those values
def isIn(x,y):
if x in y:
return True
elif y in x:
return True
else:
return 'False'
print(isIn(x,y)) #invokes and prints the results of the function evaluating
#the x and y the user inputs; otherwise nothing is returned
I'm getting the impression that you are a newcomer to Python, so here is the solution to your problem below laid out just as the question asks :)
def isIn(string_1, string_2): #This is the function that returns true/false
if (string_1 in string_2) or (string_2 in string_1):
is_in = True
else:
is_in = False
return is_in
if __name__ == "__main__":
string_1 = input ("String 1 here: ")
string_2 = input ("string 2 here: ")
is_in = isIn(string_1, string_2) #Calls function with strings as parameters
print (is_in) #Prints the evaluation of the function after it has run
The problem with your code was that you say if True, but you aren't giving it anything to check against. if True on its own is always true.
If you want me to explain how this code works in more detail I'd be happy to do so :)
you are not printing the isIn(x,y)
def is_in(x,y):
if x in y or y in x:
return True
else:
return False
print(is_in("hello","hello world"))
try this :)

Skip new line while printing with ternary operator in python

To print a statement and to prevent going into the new line one could simply add a comma in the end:
print "text",
But how can I do the same using a ternary operator? This one causes invalid syntax:
print ("A", if True else "B", )
[...] to prevent going into the new line one could simply add a comma in the end
The solution is in your question already. One could simply add a comma in the end:
print "A" if True else "B",
However Python 3 has been out for closer to a decade now so I will shamelessly plug the new print function that has much saner syntax:
from __future__ import print_function
print('A' if True else 'B', end=' ')
Future imports/Python 3 solved your problem efficiently, and the strange statement syntax is just a bad memory from past. As a plus, you're now forward-compatible!
print "A" if True else "B",
print "Hi"
Output: A Hi
I guess you can look at it this as one statement:
"A" if True else "B"
Then your print statement becomes:
print "A" if True else "B",
That should print "A" without the newline character (or "B" if the condition is False).
Instead of using just ugly hacks, we can define function called below as special_print which every print locates in the same line:
import sys
def special_print(value):
sys.stdout.write(value)
special_print('ab')
special_print('cd')
Result:
abcd
You can even mix normal print with special_print:
print('whatever')
special_print('ab')
special_print('cd')
Result:
whatever
abcd
Of course you cannot use any expression as argument of special_print, but with displaying variable it just works.
Hope that helps!
You can use the or operator as well, like this:
a = None
b = 12
print a or b,
print "is a number"
# prints: 12 is a number
Just note that the expression above is evaluated lazily, meaning that if bool(a) is False, print will return b even if that evaluates to False too since it wouldn't bother checking (therefore a or b is not equal to b or a generally speaking). In the above example for instance, if b = "" it would just print "is a number" (example).

Best way to do ternary conditionals in Python < 2.5

I have to bear with a Python version < 2.5 (it is 2.4.3 for specifics)
It seems that ternary operators were introduces in Python starting at 2.5. For those who are not familiar, ternary operators in Python >= 2.5 look like this:
def do_ternary(flag):
return "foo" if flag else "bar"
I'd like to know some solutions to emulate this in the early versions of Python. I can for sure do it with if ... else, but I'm looking for something more pythonic that I wouldn't be ashamed to put on some production-level code :)
Thanks for the help !
the correct way that does all of the things that if/else does is:
(condition and (yes_value,) or (no_value,))[0]
which does both the short circuiting and resolves the problem of when yes_value is itself falsey. Obviously, if you have reason to avoid this cludge, just do that; in your example, both conditions are constant expressions, so you can do:
{True: yes_value, False: no_value}[bool(condition)]
or more tersely:
(no_value, yes_value)[condition]
if you do need the short circut, but you're confident that the yes_value is never falsey, you can trim out the tuple:
condition and yes_value or no_value
but that's probably only valid when the yes_value is actually a constant. If none of these suit your tastes or needs, just use a plain-ol if: statement, with an intermediate variable
if condition:
result = yes_value
else:
result = no_value
Actually I was looking on the web and found what seems like a really elegant pythonic solution:
def _if(test):
return lambda alternative: \
lambda result: \
[delay(result), delay(alternative)][not not test]()
def delay(f):
if callable(f): return f
else: return lambda: f
>>> fact = lambda n: _if (n <= 1) (1) (lambda: n * fact(n-1))
>>> fact(100)
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000L
What do you think about this one? It looks pretty clean and easy to read in my opinion.
A common trick is to use list-indexing, since False/True turn into 0/1 when an integer is required. In case the test may be false-y or truth-y rather than a boolean, its good practice to first ensure the test is a boolean:
["bar", "foo"][bool(flag)]
will produce the same output as the ternary in your question.
Edit: Dougal points out that this may behave slightly differently from the ternary, because both the true and false values will be evaluated, which may have side-effects.
The classic 'trick' used to do this is:
test and true_value or false_value
This works as and and or work like so in python:
x or y -> if x is false, then y, else x
x and y -> if x is false, then x, else y
Source
This means that we get the roughly the same result - so long as true_value evaluates to True - so, for example, the following would not work:
flag and [] or "bar"
As [] evaluates to False.
I'd still argue that this is less readable than simply using an if/else block, as unless you are familiar with it, it's unclear.
So I'd advise using:
if test:
return true_value
else:
return false_value
(replacing return with assignment or whatever where needed).

Categories

Resources