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
Most of the solutions relying on if statements don't work for the case where x is 0 or negative.
>>> x = 0
>>> y = 2
>>> a = x or y
>>> a
2
>>>
If you knew the name of the variable ahead of time you could look for like so:
if 'x' in dir():
a = x
except:
a =y
However that solution seems kind of sloppy to me. I believe the best method is to use a try except block like so:
try:
a = x
else:
a = y
One way to rewrite...
if x is not None
a = x
else
a = y
..is:
x = myfunction()
if x is None:
x = y
print x
Or, using exceptions (possibly more Python'y, depending on the what the code is doing - if it returns None because there was an error, using an exception is probably the correct way):
try:
x = myfunction()
except AnException:
x = "fallback"
print x
All that said, there really isn't anything wrong with you original code:
if x is not None
a = x
else
a = y
It's long, but I find that far easier to read (and much more Pythonic) than either of the following one-liners:
a = x if x is not None else y
a = x or 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
There's python's ternary operation:
a = x if x is not None else y
Available in 2.5 and up.
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)
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;