Python中有没有与C#的空合并运算符相等的功能?

529 投票
16 回答
268356 浏览
提问于 2025-04-16 11:42

在C#中,有一个叫做空合并运算符(写作??),它可以让你在赋值时轻松地检查是否为null(空值),而且写起来很简洁:

string s = null;
var other = s ?? "some default value";

那么在Python中有没有类似的东西呢?

我知道我可以这样做:

s = None
other = s if s else "some default value"

但是有没有更简短的方法(不需要重复s)呢?

16 个回答

66

这里有一个函数,它会返回第一个不是 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
162

严格来说,

other = s if s is not None else "default value"

否则,s = False 会变成 "默认值",这可能不是你想要的结果。

如果你想让这段代码更简短,可以试试:

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() 则不会(运算符可以短路,条件运算符就是这样)。

695
other = s or "some default value"

首先,我们需要搞清楚 or 运算符是怎么工作的。它是一个布尔运算符,所以它在布尔上下文中使用。如果值不是布尔类型,它会被转换成布尔类型来进行运算。

要注意的是,or 运算符不仅仅返回 TrueFalse。相反,如果第一个操作数为真,它就返回第一个操作数;如果第一个操作数为假,它就返回第二个操作数。

在这个例子中,表达式 x or y 会返回 x,如果 xTrue 或者在转换为布尔值时为真。否则,它会返回 y。在大多数情况下,这个用法和 C♯ 的空合并运算符的效果是一样的,但要记住:

42    or "something"    # returns 42
0     or "something"    # returns "something"
None  or "something"    # returns "something"
False or "something"    # returns "something"
""    or "something"    # returns "something"

如果你用变量 s 来存放一个类的实例引用或者 None(只要你的类没有定义 __nonzero__()__len__()),那么使用和空合并运算符相同的语义是安全的。

实际上,利用 Python 的这种特性可能会很有用。因为你知道哪些值会被认为是假的,你可以用这个特性来触发默认值,而不需要特别使用 None(比如一个错误对象)。

在某些编程语言中,这种行为被称为 Elvis 运算符

撰写回答