Possible Duplicate:
Python conditional assignment operator
Apologies for such a simple question, but googling ||=
isn't very helpful ;)
Is there an equivalent in Python to the ||=
statement that's present in Ruby and Perl?
For example:
foo = "hey"
foo ||= "what" # assign foo if it's undefined
# foo is still "hey"
bar ||= "yeah"
# bar is "yeah"
Also what's the general term for something like this? Conditional assignment was my first guess but the Wikipedia page isn't quite what I had in mind.
A tad bit more verbose, but the easiest is
foo = "hey"
foo = foo or "what"
#foo is still "hey"
bar = None
bar = bar or "yeah"
#bar is "yeah"
You can also use the ternary operator
bar = None
bar = bar if bar else "yeah"
However, if I understand you, ||=
assigns variables that weren't previously defined, without complaint? I had no idea.
To do that in the local scope, this ugly duckling could work
bar = locals()['bar'] if 'bar' in locals() else 'yeah'
EDIT:
Just saw the duplicate, and it has plenty of solutions as well :) For those too lazy to look, they also include a nicer variant on my last one
foo = foo if 'foo' in locals() else 'hey'
but this won't work for undefined variables, only falsy values will be replaced and undefined will raise a NameError
. This next one will, OTOH, ONLY work for undefined and always keep the same preexisting falsy value, which as @Borodin says is like //=
in Perl
foo = locals().get('foo','hey')
and, of course, someone used an exception :(
try:
v
except NameError:
v = 'bla bla'
You'll hardly ever have undefined variables in Python, and when you do it usually means you have made a mistake. However, conveniently, most of the sorts of values that are commonly used as defaults (empty containers, zero-length strings, zero, and None
) are "falsy" in Python, so you will sometimes see stuff like this that takes advantage of how Boolean operators work in Python:
name = name or "Guido" # if name is empty, set it to "Guido"
numb = numb or 42 # if numb is zero, set it to 42
The reason this works is that Python stops evaluating or
if the first argument is "truthy," which is called short-circuiting, and in either case returns the actual argument, rather than merely True
or False
, as its result. So if name
is "Jim" then "Jim" or "Guido"
evaluates to "Jim"
because "Jim"
is a non-zero-length string and therefore "truthy."
Of course, this doesn't work so well when you don't know the type of the value you're dealing with and/or a "falsy" value is a valid value. However, it works pretty well with things like configuration files and raw_input()
where a missing value will return an empty string:
name = raw_input("What is your name? ") or "Guido"
Another common idiom is used when dealing with items in a dictionary. The dictionary class's get()
method lets you specify a default value to be used if the variable isn't in the dictionary.
name = values.get("name", "Guido")
This can be used when your function has been passed keyword arguments using the **kwargs
convention. You could also use it with variables, as the globals()
and locals()
functions return, respectively, all global or local variables currently in scope as a dictionary:
name = locals().get("name", "Guido")
However, as I said, you will rarely ever have actually undefined variables in Python. In cases like Web frameworks, you'll be passed query string arguments as a dictionary, for example, and can use the dictionary's .get()
method on it.
In the rare case where a name actually does not exist (for example, your configuration file is in Python syntax and you're importing it as a Python module rather than parsing it, and you want users to be able to omit some values... or something equally wacky) then you can use getattr()
, which (like dictionary's .get()
) accepts a default value:
import config
name = getattr(config, "name", "Guido") # rather than just name.config
Or just let it throw a NameError
and catch it.
Not sure about the name. The best I could come up with is:
>>> a = 'foo'
>>> a = 'a' in locals() and a or 'what'
>>> a
'foo'
>>> b = 'b' in locals() and b or 'yeah'
>>> b
'yeah'
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