Python:如果不存在,则指定值
我是Python的新手。我试图找到一种语法,这种语法允许我仅在之前未赋值的情况下将变量设置为特定值。基本上我想要:Python:如果不存在,则指定值,python,python-2.7,variable-assignment,language-comparisons,Python,Python 2.7,Variable Assignment,Language Comparisons,我是Python的新手。我试图找到一种语法,这种语法允许我仅在之前未赋值的情况下将变量设置为特定值。基本上我想要: # only if var1 has not been previously assigned var1 = 4 您应该将变量初始化为“无”,然后检查它: var1 = None if var1 is None: var1 = 4 可在一行中写为: var1 = 4 if var1 is None else var1 或使用快捷方式(但建议不选中任何快捷方式) 或者
# only if var1 has not been previously assigned
var1 = 4
您应该将变量初始化为“无”,然后检查它:
var1 = None
if var1 is None:
var1 = 4
可在一行中写为:
var1 = 4 if var1 is None else var1
或使用快捷方式(但建议不选中任何快捷方式)
或者,如果您没有为变量分配任何内容,那么该变量名不存在,因此以后使用该变量将引发namererror
,您也可以使用该知识执行类似操作
try:
var1
except NameError:
var1 = 4
但是我建议不要这样做。如果您是指模块级别的变量,那么您可以使用“全局变量”:
但是常见的Python习惯用法是将其初始化为
None
(假设它不是一个可接受的值),然后使用测试var1是否为None
这是一种非常不同的编程风格,但我总是尝试重写看起来像
bar = None
if foo():
bar = "Baz"
if bar is None:
bar = "Quux"
仅限于:
if foo():
bar = "Baz"
else:
bar = "Quux"
也就是说,我尽量避免出现某些代码路径定义变量而其他路径不定义变量的情况。在我的代码中,从来没有一条路径会导致定义的变量集出现歧义(事实上,我通常会更进一步,并确保无论代码路径如何,类型都是相同的)。这可能只是个人品味的问题,但我发现这种模式,虽然在我写它时不太明显,但在我以后阅读它时更容易理解
var1 = var1 or 4
这可能存在的唯一问题是,如果var1是一个假值,如False、0或[],它将选择4。这可能是一个问题。IfLoop的答案(以及MatToufoutu的评论)对于独立变量非常有效,但我想为任何试图对列表、元组或字典中的单个条目执行类似操作的人提供一个答案
字典
existing_dict = {"spam": 1, "eggs": 2}
existing_dict["foo"] = existing_dict["foo"] if "foo" in existing_dict else 3
existing_list = ["spam","eggs"]
existing_list = existing_list if len(existing_list)==3 else
existing_list + ["foo"]
existing_tuple = ("spam","eggs")
existing_tuple = existing_tuple if len(existing_tuple)==3 else
existing_tuple + ("foo",)
返回{“垃圾邮件”:1,“鸡蛋”:2,“食物”:3}
列表
existing_dict = {"spam": 1, "eggs": 2}
existing_dict["foo"] = existing_dict["foo"] if "foo" in existing_dict else 3
existing_list = ["spam","eggs"]
existing_list = existing_list if len(existing_list)==3 else
existing_list + ["foo"]
existing_tuple = ("spam","eggs")
existing_tuple = existing_tuple if len(existing_tuple)==3 else
existing_tuple + ("foo",)
返回[“垃圾邮件”、“鸡蛋”、“食物”]
元组
existing_dict = {"spam": 1, "eggs": 2}
existing_dict["foo"] = existing_dict["foo"] if "foo" in existing_dict else 3
existing_list = ["spam","eggs"]
existing_list = existing_list if len(existing_list)==3 else
existing_list + ["foo"]
existing_tuple = ("spam","eggs")
existing_tuple = existing_tuple if len(existing_tuple)==3 else
existing_tuple + ("foo",)
返回(“垃圾邮件”、“鸡蛋”、“食物”)
(不要忘记在(“foo”)中使用逗号来定义“单个”元组。)
如果您想做的不仅仅是检查长度和追加到末尾,那么列表和元组解决方案将更加复杂。尽管如此,这给了你一种你能做什么的感觉。我也来自Ruby,所以我喜欢语法foo | |=7
这是我能找到的最接近的东西
foo = foo if 'foo' in vars() else 7
我见过人们这样做是为了口述:
try:
foo['bar']
except KeyError:
foo['bar'] = 7
Upadate:
然而,我最近发现了这个宝石:
foo['bar'] = foo.get('bar', 7)
如果您喜欢,那么对于正则变量,您可以执行以下操作:
vars()['foo'] = vars().get('foo', 7)
这是我用的最简单的方法希望对你有用
var1=var1或var4
仅当var1
为None
、False
或0
时,才会将4
分配给var1
,此处为一个线性解决方案:
var1=locals().get(“var1”,“默认值”)
如果尚未定义var1
,此解决方案将var1
设置为默认值,而不是namererror
以下是Python交互式shell中的外观:
>>var1
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
NameError:未定义名称“var1”
>>>var1=locals().get(“var1”,“默认值1”)
>>>var1
“默认值1”
>>>var1=locals().get(“var1”,“默认值2”)
>>>var1
“默认值1”
>>>
那就是疯狂。这会在局部变量上使用locals()
在全局变量上使用中断,我认为这两种方法都不适用于非局部变量。要解决这个问题,必须模拟整个作用域规则或编写假定两者之一的代码。@delnan:About local/nonglobal这就是我所说的“If you mean a variable at module level”的意思。关于那个愚蠢的“疯狂就在那里”你应该告诉OP,而不是我。。。顺便说一下,答案中实际上告诉我们这不是应该怎么做的。在什么情况下,您会引用可能不存在的变量?是否要引用已声明但尚未初始化的变量?请注意,如果要分配值,则需要全局
/非局部
声明,或使用除UnboundLocalError外的(并接受该变量将是局部的,全局设置的值将被忽略)。由于后面的赋值(在中,除
)之外,var1
是一个局部变量,除非代码段处于模块(即全局)级别或有一行全局var1
。访问尚未分配的局部变量会引发UnboundLocalError
而不是NameError
(这是为全局名称保留的)。@delnan我不明白,你能举个例子来说明这一点吗,因为>>issubclass(UnboundLocalError,NameError)True
哦,该死,我总是忘记了子类型关系。你的代码确实是正确的。很抱歉造成混淆。var1=var1或4
如果var1是0
,则会对您造成伤害,因为0
是一个错误的值,因此0或4
的计算结果为4
,在本例中您不会这样做。您可以使用bar=“Baz”if foo()或“qux”
What is foo(),检查在本例中计算为“false”的其他内容,甚至可以在一行中缩短这些内容?这是怎么回答这个问题的?回复不包括根据变量的存在对其进行条件赋值。请小心,如果任何预期值都是错误的(例如,False
,0
,'
,[]
,{}
)。如果x不是其他x,那么最好说x=y
@mdeale这是错误的,因为foo()==False将使bar成为“qux”。您的Python解决方案质量一般。@HenryHenrinson不正是这样吗