Assign two variables with ternary operator - python

Is there a way to do variable assignments(as shown below) using ternary operators in python:
if(x>1):
y="yes"
else:
z="yes"
Something like (x='yes') if(x>1) else (z='yes'), but this gives an error. Is there any other way to do this?
I know single variable assignments can be done like this: x="yes" if(l==0) else "no"
Edit: Assume x, y & z are assigned with some value before this is run.

You can use the following hack, which employs tuple unpacking:
y, z = ('yes', z) if x > 1 else (y, 'yes')
Don't miss those parentheses.
I wouldn't really recommend using this as it is harder to understand, has one redundant assignment statements, and uses unpacking unnecessarily. I'd recommend going for the normal if statement wherever you can.
This is what it would be with normal ifs:
if x > 1:
y = 'yes'
z = z
else:
y = y
z = 'yes'

No, you can't do that. You can only have expressions, not statements, inside the ternary. print works because (in Python 3 at least) it is a function call, therefore an expression; but assignment is always a statement.

varname = 'y' if x > 1 else 'z'
If you want to assign a global variable:
globals()[varname] = 'yes'
If you want to set an attribute on an object:
setattr(obj, varname, 'yes')
If it's a local variable inside a function, you have to get more hacky:
exec('%s = "yes"' % varname)
or
exec(varname + ' = "yes"')
You can of course place the definition of varname directly in all of these statements to keep it in one line, I'm just avoiding repetition.
But really it's best to not do any of these. Keep it simple and straightforward.

You can use exec function like this:
exec("y='yes'" if x > 1 else "z='yes'")

Related

Why is print(x += 1) invalid syntax?

This works just fine
x = 0
while True:
x += 1
print(x)
while this
x = 0
while True:
print(x += 1)
doesn't
I want a program that counts to infinity or at least until max digits
Unlike many other languages, where an assignment is an expression and evaluates to the assigned value, in Python an assignment is its own statement. Therefore it can't be used in an expression.
One advantage of this is that if you forget an = in an if statement (i.e. you meant to write == but wrote = instead) you get an error:
if a = b: # this is an assignment not a comparison! SyntaxError
In certain other languages this is valid syntactically but wouldn't give you the result you intend, causing hair-loss bugs. (This is one reason linters were invented. The language itself didn't prevent you from making this mistake, so they created an external tool to help with that.)
Python 3.8 adds the assignment operator, :=, a.k.a. the walrus operator. It behaves like assignment in other languages, although you still can't use it everywhere. So this works:
x = 0
while True:
print(x := x + 1)
Unfortunately (or fortunately) there is no +:=, which I guess you'd call an augmented walrus.
Because the argument to print() needs to be an expression, and an assignment statement is not an expression.
The walrus operator := was introduced in Python precisely to allow you to do this, though it does not have a variant which allows you to increment something. But you can say
x = 0
while True:
print(x := x + 1)
This does not strike me as a particularly good or idiomatic use of this operator, though.

If X or Y or Z then use *that* one?

Is there a way to write an If (or equivalent) statement that can have many arguments, and if any of those satisfy the logic, use that variable?
For instance
if len(x) == 1 or len(y) == 1 or len(z) == 1 or ... len(zz) == 1:
# do something with the variable that met the condition
So say only z has length 1, could I write above idea/formula in a way that takes the first True answer and use that?
So something like
x = "123"
y = "234"
z = "2"
xx = "1234"
yy = "12345"
if len(x) == 1 or len(y) == 1 or len(z) == 1 or len(xx) == 1 or len(yy) == 1:
#do something with the variable that satisfies the condition, so `z` in this case.
Does that make any sense? The variables' lengths could change any time, so I'd like to be able to say "If any of the conditions are met, use the variable that met the condition"...?
In the above, I don't know beforehand that zwill be the only one to meet the criteria, so my Then statement can't be z = "new value" or whatever I want
to do with it.
Edit: Sorry, per comments I know checking for len on integers isn't okay. This is solely for illustration purposes and it was the first thing I thought of to "test". Sorry if the len bit is confusing. I'm mainly just trying to see if I can use If statements (or related ones) where I don't know which of my many variables will meet a condition. (I'm still new regarding python, so my sincere apologies for my lack of semantics or proper terms). I'd like to avoid elif if at all possible just because it can get stringy. (But if that's the most pythonic way, then so be it!)
While #pault 's answer addresses your question, I think it isn't super readable.
If you have a couple of variables only, pythons mantra dictate a straightforward, explicit way:
if len(x) == 1:
f(x)
elif len(y) == 1:
f(y)
elif len(z) == 1:
f(z)
Otherwise, if you have a list, a for loop is readable and efficient:
for l in ls:
if len(l) == 1:
f(l)
break
You could use next here to pick the first item out of a list of options that meets your criteria:
value = next((item for item in [x, y, z] if len(item)==1), None)
if value is not None:
...
The second argument to next() is the default value if no values meet your criteria.
What you describe has a general implementation called first_true in the itertools recipes.
def first_true(iterable, default=False, pred=None):
"""Returns the first true value in the iterable.
If no true value is found, returns *default*
If *pred* is not None, returns the first item
for which pred(item) is true.
"""
# first_true([a,b,c], x) --> a or b or c or x
# first_true([a,b], x, f) --> a if f(a) else b if f(b) else x
return next(filter(pred, iterable), default)
Example
value = first_true([x, y, z], pred=lambda x: len(x) == 1)
if value:
...
A small list comprehension would suffice:
passed = [i for i in (x, y, z, xx, yy) if len(i) == 1]
if passed:
# ... use the ones that passed, or 'passed[0]' for the first item

Double variable if statement not working

I'm making a double variable if statement and it keeps returning an error. I don't know what's wrong:
variable = float(0)
for index in range(10):
variable = variable + float(2)
if x <= float(variable/3) and > float(variable-2.0/3):
# do something
else:
pass
or something like that. This is the basic structure. Why does it keep highlighting the > in red whenever I try to run it?
Python supports regular inequalities as well, so you could just write this:
if variable - 2.0 / 3 < x <= variable / 3:
# ...
You want to do something like
if ((x <= float(variable/3)) and (x > float(variable-2.0/3))):
# do something
else:
pass
In other words, each side of the and must be a boolean expression on its own. I'm not sure whether you need all the parenthesis.
It seems like you're missing a variable or constant before the second condition in the if-block. That might be one reason you're getting an error.
This code works fine:
index=0
x=0
variable = float(0)
for index in range(10):
variable=variable + float(2)
if x <= float(variable/3) and x> float(variable-2.0/3):
print 'Doesn\'t Matter'
else:
print 'pass'

python (bool) ? then : else syntax? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python Ternary Operator
In some languages including Java, C/C++, C#, etc. you can assign a value based on the result of an inline boolean expression.
For example,
return (i < x) ? i : x
This will return i if i < x, otherwise it will return x. I like this because it is much more compact in many cases than the longer syntax which follows.
if (i < x)
return i
else
return x
Is it possible to use this syntax in python and if so, how?
You can use (x if cond else y), e.g.
>>> x = 0
>>> y = 1
>>> print("a" if x < y else "b")
a
That will work will lambda function too.
Yes, it looks like this:
return i if i < x else x
It's called the conditional operator in python.
a if b else c syntax was introduced in Python 2.5. Most people have already upgraded to the recent version but in legacy code you may find another approach:
some_var = a<b and a or c
If you ever will be using this syntax remember that a must not evaluate to False.
As the other answers state, Python's version for this is:
i if i < x else x
(of course for this particular example, one would prefer writing
min(i, x) , as it is easier on the eyes)
However, this expression syntax was just made available on Python 2.5 (I think it was around 2004). before that, the following idiom was used - but care should be taken, as it is error prone:
i < x and i or x - because the logical operator "and" actually evaluates to the last true value on its chain - therefore, if the expression was true, i < x and i evaluates to i - and the or operator evaluates to first true value on the chain. On this case, if i < x would be false, so would i< x and i and the first true value would be x.
It is easy to see how error prone this construct was, since if the boolean value of i would be false ( for example if i==0), than it would return x, even if i < x where true.
I myself, back in those days, used to write this construct instead:
(x, i)[i < x]
The expression "i < x" ha a numerical value of "1" (true) or "0" (false) and I used this proeprty to have it work as an index to the previous tuple. The problem with this approach was that it would always evaluate both expressions on the tuple, even though it would use ony one of then (if the expressions where function calls this could get expensive, or even conflicting)
Ternary operator in python.
a if b else c
>>> a=1
>>> b=2
>>> a if a<b else b
1
>>> a if a>b else b
2
Try this in Python:
return i if i < x else x
It's exactly the equivalent of the following expression in Java, C, C++ C#
return i < x ? i : x;
Read more about Python's conditional expressions.

rewrite small piece of python code

I have lots of small pieces of code that look like:
for it in <iterable>:
if <condition>:
return True/False
Is there a way I can rewrite this piece of code with a lambda expression ? I know I can factor it out in a small method/function, but I am looking for some lambda thing if it can be done.
Use the built-in any function.
e.g.
any(<condition> for it in <iterable>) # return True on <condition>
In addition to what everyone else has said, for the reverse case:
for it in <iterable>:
if <condition>:
return False
return True
use all():
b = all(<condition> for it in <iterable>)
if you want to check the condition for every item of iterable you can use
listcomprehensions to to this
b = [ x == whatever for x in a ]
you can combine this with any if you only need to know if there is one element
that evals to true for your condition
b = any(x == whatever for x in a)
Here is a simple example which returns True if any of the objects in it is equal to 2. by using the map function:
any(map(lambda x: x==2, it))
Change the lambda expression to reflect your condition.
Another nice way is to use any with a list comprehension:
any([True for x in it if x==2])
or alternatively, a generator expression:
any(x==2 for x in it)

Categories