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(falsenil)则设置。当然,这种区别在语言中更为重要,例如将 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。”但是,如果您需要 None0False"" 为有效值,则需要更改此行为,例如:

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 "", line 1, in NameError: name 'x' is not defined 这是一个错误的答案,如果 x 不存在就会失败。由于该问题要求一种测试存在性的方法,因此该解决方案将不起作用。 这个答案解决了“条件赋值”的问题。如果没有设置变量,则设置它。当然,右边的一切都必须定义,否则会报错(我只是把它当作伪代码)。 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 use except: @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 条件赋值运算符的主要内容,如果未能解决你的问题,请参考以下文章

Python基础(while循环/赋值运算符)

python 运算/赋值/循环

Coffeescript 中的存在条件赋值运算符

三元条件和赋值运算符优先级

赋值运算符左侧的三元条件运算符

python中运算符都有哪些