Python 条件赋值运算符
Posted
技术标签:
【中文标题】Python 条件赋值运算符【英文标题】:Python conditional assignment operator 【发布时间】:2011-09-18 03:23:14 【问题描述】:是否存在等效于 Ruby ||=
运算符(“如果未设置变量,请设置变量”)的 Python?
Ruby 中的示例:
variable_not_set ||= 'bla bla'
variable_not_set == 'bla bla'
variable_set = 'pi pi'
variable_set ||= 'bla bla'
variable_set == 'pi pi'
【问题讨论】:
如果未设置则不设置 - 如果当前值为 false(false
或 nil
)则设置。当然,这种区别在语言中更为重要,例如将 0 和 "" 视为 false,但仍然
这个 ruby 运算符的用例是什么?
这样做的方法是使用除 phihag 指示的 NameError 之外的尝试,但这在 Python 中没有任何意义,正如这里每个人所说的那样。在 Ruby 中,由于人们传递任意代码块以在函数内部运行的方式,它更有用。目标函数可能需要设置一个未在其执行的外部块中初始化的变量。 Python 中没有这种情况。
【参考方案1】:
我很惊讶没有人提供这个答案。它不像 Ruby 的 ||=
那样“内置”,但它基本上是等效的,并且仍然是单行的:
foo = foo if 'foo' in locals() else 'default'
当然,locals()
只是一个字典,所以你可以这样做:
foo = locals().get('foo', 'default')
【讨论】:
【参考方案2】:我会用
x = 'default' if not x else x
比您在此处建议的所有替代方案短得多,而且直截了当。阅读,“如果未设置 x,则将 x 设置为‘默认’,否则将其保留为 x。”但是,如果您需要 None
、0
、False
或 ""
为有效值,则需要更改此行为,例如:
valid_vals = ("", 0, False) # We want None to be the only un-set value
x = 'default' if not x and x not in valid_vals else x
这种东西也只是乞求变成一个你可以在任何地方轻松使用的功能:
setval_if = lambda val: 'default' if not val and val not in valid_vals else val
此时,您可以将其用作:
>>> x = None # To set it to something not valid
>>> x = setval_if(x) # Using our special function is short and sweet now!
>>> print x # Let's check to make sure our None valued variable actually got set
'default'
最后,如果你真的缺少你的 Ruby 中缀符号,你可以按照这个人的 hack 来重载 ||=|
(或类似的东西):http://code.activestate.com/recipes/384122-infix-operators/
【讨论】:
你的第一个例子不起作用:>>> x = 'default' if not x else x Traceback (last recent call last): File "x = "value1" if True else "value2"
。一般来说。 x = 'value1' if condition else 'value2'
【参考方案3】:
不,替换是:
try:
v
except NameError:
v = 'bla bla'
但是,想要使用这种结构是代码流过于复杂的标志。通常,您会执行以下操作:
try:
v = complicated()
except ComplicatedError: # complicated failed
v = 'fallback value'
永远不要不确定是否设置了v
。如果它是可以设置或不设置的众多选项之一,请使用字典及其允许默认值的 get
方法。
【讨论】:
不,你don't useexcept:
。
@delnan 我不想对complicated()
的性质做出具体假设。已添加。
你确定? @emish 提供了一个更简单的解决方案。
这是一个糟糕的解决方案。它不仅更复杂,而且在性能方面也更差。我会尽可能建议从问题中删除此解决方案。【参考方案4】:
在 Python 2.5 及更高版本中有条件赋值 - 语法不是很明显,因此很容易错过。以下是你的做法:
x = true_value if condition else false_value
如需进一步参考,请查看Python 2.5 docs。
【讨论】:
这不是我们要求的。【参考方案5】:不,不知道定义了哪些变量是一个错误,而不是 Python 中的一个特性。
改用字典:
d =
d.setdefault('key', 1)
d['key'] == 1
d['key'] = 2
d.setdefault('key', 1)
d['key'] == 2
【讨论】:
【参考方案6】:(不能发表评论,否则我会这样做)我认为上面检查当地人的建议不太正确。应该是:
foo = foo if 'foo' in locals() or 'foo' in globals() else 'default'
在所有情况下都是正确的。
然而,尽管它得到了支持,但我认为这也不能很好地模拟 Ruby 运算符。由于 Ruby 运算符允许的不仅仅是左侧的简单名称:
foo[12] ||= something
foo.bar ||= something
异常方法可能最接近模拟。
【讨论】:
【参考方案7】:我通常这样做:
def set_if_not_exists(obj,attr,value):
if not hasattr(obj,attr): setattr(obj,attr,value)
【讨论】:
【参考方案8】:我认为你在找什么,如果你在字典里找东西,是setdefault
方法:
(Pdb) we=dict()
(Pdb) we.setdefault('e',14)
14
(Pdb) we['e']
14
(Pdb) we['r']="p"
(Pdb) we.setdefault('r','jeff')
'p'
(Pdb) we['r']
'p'
(Pdb) we[e]
*** NameError: name 'e' is not defined
(Pdb) we['e']
14
(Pdb) we['q2']
*** KeyError: 'q2' (pdb)
在我的示例中需要注意的重要一点是,当且仅当 setdefault
方法引用的键不存在时,setdefault
方法才会更改字典。
【讨论】:
【参考方案9】:我这样做...只是分享以防它对 OP 或其他任何人有用...
def iff(value, default):
return default if not value else value
用法:
z = iff(x,y) # z = x if and only if x is not null otherwise y
【讨论】:
【参考方案10】:我不确定我是否正确理解了这里的问题...尝试“读取”“未定义”变量名的值将触发NameError
。 (见here, that Python has "names",不是变量...)。
== 编辑 ==
正如 delnan 在 cmets 中指出的那样,下面的代码并不健壮,并且会在很多情况下中断...
尽管如此,如果您的变量“存在”,但具有某种虚拟值,例如 None
,则以下方法可行:
>>> my_possibly_None_value = None
>>> myval = my_possibly_None_value or 5
>>> myval
5
>>> my_possibly_None_value = 12
>>> myval = my_possibly_None_value or 5
>>> myval
12
>>>
(见this paragraph about Truth Values)
【讨论】:
只要值可能是 0、“”、空字符串或其他任何“虚假”的值,就会中断。明确检查是否为is None
。
哦,是的,你是对的,我没有想到这一点。感谢您的提示!我实际上从来没有需要做这个“或”的事情,我认为这是对这个问题的一个有效答案......但这个问题本身似乎与 Python 无关......以上是关于Python 条件赋值运算符的主要内容,如果未能解决你的问题,请参考以下文章