In Perl, it's often nice to be able to assign an object, but specify some fall-back value if the variable being assigned from is 'undef'. For instance:
my $x = undef;
my $y = 2;
my $a = $x || $y;
After this,
$a == 2
Is there a concise way to achieve this in Python if the value x is None, or would a full-on ...
if x is not None
a = x
else
a = y
... be the most Pythonic way to achieve this?
EDIT: Apologies, as has been pointed out by several commenters, I wasn't really talking about the value being undefined, but 'undef' in Perl, which is not really the same thing. But the question as originally worded didn't make this clear.
Since 2.5:
If you want to fall back only on None:
a = x if x is not None else y
If you want to fall back also on empty string, false
, 0
etc.:
a = x if x else y
or
a = x or y
As for undefined (as never defined, a.k.a. not bound):
try:
a = x
except NameError:
a = y
or a bit more hackish (I'd not really recommend that, but it's short):
a = vars().get('x',y)
first you can do your full-on with a ternary:
a = y if x is None else x
but it doesn't solve your problem. what you want to do is more closely implemented with:
try:
a = x
except:
a = y
Just some nitpicking with your Perl example:
my $x = undef;
This redundant code can be shortened to:
my $x;
And the following code doesn't do what you say it does:
my $a = $x || $y;
This actually assigns $y to $a when $x is false. False values include things like undef
, zero, and the empty string. To only test for definedness, you could do the following (as of Perl 5.10):
my $a = $x // $y;
I am quite convinced that there is no 'pythonic' way to do this, because this is not a pattern that is pythonic. Control should not reach an undefined variable reference in elegant code. There are similar ideas that are pythonic. Most obvious:
def myRange(start, stop=None):
start, stop = (0, start) if stop is None else (start, stop)
...
What's important is that stop
is defined in scope, but the caller didn't have to pass it explicitly, only that it has taken it's default value, altering the semantics of the arguments, which in effect causes the first argument to be optional instead of the second, even where the language does not allow that without this clever trick.
That being said, something like this might follow the premise without using a try-catch block.
a = locals().get('x', y)
There's python's ternary operation:
a = x if x is not None else y
Available in 2.5 and up.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With