Python: Assign Value if None Exists

2019-02-03 22:58发布

I am a RoR programmer new to Python. I am trying to find the syntax that will allow me to set a variable to a specific value only if it wasn't previously assigned. Basically I want:

# only if var1 has not been previously assigned

var1 = 4

6条回答
迷人小祖宗
2楼-- · 2019-02-03 23:27

This is a very different style of programming, but I always try to rewrite things that looked like

bar = None
if foo():
    bar = "Baz"

if bar is None:
    bar = "Quux"

into just:

if foo():
    bar = "Baz"
else:
    bar = "Quux"

That is to say, I try hard to avoid a situation where some code paths define variables but others don't. In my code, there is never a path which causes an ambiguity of the set of defined variables (In fact, I usually take it a step further and make sure that the types are the same regardless of code path). It may just be a matter of personal taste, but I find this pattern, though a little less obvious when I'm writing it, much easier to understand when I'm later reading it.

查看更多
冷血范
3楼-- · 2019-02-03 23:32

IfLoop's answer (and MatToufoutu's comment) work great for standalone variables, but I wanted to provide an answer for anyone trying to do something similar for individual entries in lists, tuples, or dictionaries.

Dictionaries

existing_dict = {"spam": 1, "eggs": 2}
existing_dict["foo"] = existing_dict["foo"] if "foo" in existing_dict else 3

Returns {"spam": 1, "eggs": 2, "foo": 3}

Lists

existing_list = ["spam","eggs"]
existing_list = existing_list if len(existing_list)==3 else 
                existing_list + ["foo"]

Returns ["spam", "eggs", "foo"]

Tuples

existing_tuple = ("spam","eggs")
existing_tuple = existing_tuple if len(existing_tuple)==3 else 
                 existing_tuple + ("foo",)

Returns ("spam", "eggs", "foo")

(Don't forget the comma in ("foo",) to define a "single" tuple.)

The lists and tuples solution will be more complicated if you want to do more than just check for length and append to the end. Nonetheless, this gives a flavor of what you can do.

查看更多
Fickle 薄情
4楼-- · 2019-02-03 23:36

I'm also coming from Ruby so I love the syntax foo ||= 7.

This is the closest thing I can find.

foo = foo if 'foo' in vars() else 7

I've seen people do this for a dict:

try:
    foo['bar']
except KeyError:
    foo['bar'] = 7

Upadate: However, I recently found this gem:

foo['bar'] = foo.get('bar', 7)

If you like that, then for a regular variable you could do something like this:

vars()['foo'] = vars().get('foo', 7)
查看更多
迷人小祖宗
5楼-- · 2019-02-03 23:39

You should initialize variables to None and then check it:

var1 = None
if var1 is None:
    var1 = 4

Which can be written in one line as:

var1 = 4 if var1 is None else var1

or using shortcut (but checking against None is recommended)

var1 = var1 or 4

alternatively if you will not have anything assigned to variable that variable name doesn't exist and hence using that later will raise NameError, and you can also use that knowledge to do something like this

try:
    var1
except NameError:
    var1 = 4

but I would advise against that.

查看更多
Fickle 薄情
6楼-- · 2019-02-03 23:39
var1 = var1 or 4

The only issue this might have is that if var1 is a falsey value, like False or 0 or [], it will choose 4 instead. That might be an issue.

查看更多
SAY GOODBYE
7楼-- · 2019-02-03 23:49

If you mean a variable at the module level then you can use "globals":

if "var1" not in globals():
    var1 = 4

but the common Python idiom is to initialize it to say None (assuming that it's not an acceptable value) and then testing with if var1 is not None.

查看更多
登录 后发表回答