这个pythonic惯用法有没有"官方"指导方针?
这个pythonic惯用法有没有"官方"指导方针?
在C#中有一个空合并运算符(写作??
),可以在赋值过程中方便地进行(简短的)空值检查:\n
string s = null; var other = s ?? "some default value";
\n在Python中是否有相应的功能?\n我知道可以这样做:\n
s = None other = s if s else "some default value"
\n但是否有更简短的方法(无需重复s
)?
这是一个返回第一个不是None的参数的函数:
def coalesce(*arg): return reduce(lambda x, y: x if x is not None else y, arg) # Prints "banana" print coalesce(None, "banana", "phone", None)
reduce()函数可能会不必要地迭代所有的参数,即使第一个参数不是None,所以你也可以使用这个版本:
def coalesce(*arg): for el in arg: if el is not None: return el return None
`def coalesce(*arg): return next((a for a in arg if a is not None), None)` 在一行中完成了和最后一个示例相同的功能。
我明白人们想要解释if else语法等,但是coalesce接受一个任意数量的参数,所以这应该是最好的答案。
glglgl有最好的答案。我在一个大的测试数组上使用了timeit,reduce实现的速度太慢了,多行的for/if版本最快,而next版本稍微慢一些。考虑到简洁性和简洁性,next版本是最好的。
有趣的代码片段。不幸的是,由于Python没有按名称传递,像这样的coalesce不是短路的;在代码运行之前,所有的参数都会被求值。
这对我来说是有效的,但是在Python 3中(Python 2现在已经EOL),需要`from functools import reduce`。此外,`print`现在是一个返回`None`的函数,而不是一个语句。
有没有关于这个pythonic习语的“官方”指南?
严格来说,other = s if s is not None else "default value"
的作用是,如果s不为None,则将s赋值给other,否则将"default value"赋值给other。否则,s=False将变成"default value",这可能不是预期的结果。
如果你想让这个过程更简洁,可以尝试以下代码:
def notNone(s,d): if s is None: return d else: return s other = notNone(s, "default value")
需要注意的是,由于这是一个函数,如果第一个值不是None,它不会像条件运算符那样短路;相反,它会评估两个参数,即使第二个参数最终没有被使用。例如,如果a不是None,notNone(a, get_some_value())
仍然会调用get_some_value
,但a if a is not None else get_some_value()
不会(运算符可以短路,条件运算符也可以)。
这应该是答案。
我想知道如果我的情况是other = s.name if s is not None else "default value"
,是否也有像notNone
这样更简洁的方式?
这应该是答案,Python可以考虑添加这样一个方便的运算符。
有一个常见的Python习惯用法是使用or
操作符来设置默认值。这种用法的原因是or
操作符在布尔上下文中起作用,如果操作数不是布尔值,会被转换成布尔值。该操作符不仅返回True
或False
,而是返回第一个操作数(如果第一个操作数为真),或者返回第二个操作数(如果第一个操作数为假)。
使用or
操作符可以实现类似于C♯中的空值合并操作符的功能。在大多数情况下,这种用法能够满足需求,但需要注意一些细节。例如,数字0、None
和空容器(包括空字符串)被认为是假值,除此之外的大多数值都被认为是真值。因此,在使用or
操作符设置默认值时,可能会得到一个真值但非字符串类型的结果。
这种用法甚至可以用于默认值本身为假值的情况,例如{}
。通过将变量赋值为None
,然后使用or
操作符设置默认值,可以实现这一功能。
然而,这种用法也存在一些问题和不足。例如,在Python 3.5之前,datetime.time(0)
也被认为是假值。另外,如果s
的值既不是None
也不是真值,使用这种方法将会得到默认值,这可能不是预期的结果。
因此,建议在使用or
操作符设置默认值时要谨慎,并考虑是否存在更合适的替代方案。例如,可以使用条件表达式"some default value" if s is None else s
来达到相同的效果。
使用or
操作符来设置默认值是一种常见的Python习惯用法,但在实际使用时需要注意其局限性和潜在的问题。