是否存在与c# null-coalescing运算符等价的Python ?

时间:2021-04-29 11:46:24

In C# there's a null-coalescing operator (written as ??) that allows for easy (short) null checking during assignment:

c#中有一个null-coalescing运算符(写成?? ?

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

Is there a python equivalent?

是否存在与python等价的?

I know that I can do:

我知道我能做到:

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

But is there an even shorter way (where I don't need to repeat s)?

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

5 个解决方案

#1


262  

other = s or "some default value"

Ok, it must be clarified how the or operator works. It is a boolean operator, so it works in a boolean context. If the values are not boolean, they are converted to boolean for the purposes of the operator.

好的,必须弄清楚or运算符是如何工作的。它是一个布尔运算符,所以它在布尔上下文中工作。如果值不是布尔值,则为操作符的目的将其转换为布尔值。

Note that the or operator does not return only True or False. Instead, it returns the first operand if the first operand evaluates to true, and it returns the second operand if the first operand evaluates to false.

注意or操作符不仅返回True或False。相反,如果第一个操作数计算为true,则返回第一个操作数,如果第一个操作数计算为false,则返回第二个操作数。

In this case, the expression x or y returns x if it is True or evaluates to true when converted to boolean. Otherwise, it returns y. For most cases, this will serve for the very same purpose of C♯'s null-coalescing operator, but keep in mind:

在这种情况下,如果表达式x或y为真,则返回x;如果它为真,则返回x;否则,它将返回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"

If you use your variable s to hold something that is either a reference to the instance of a class or None (as long as your class does not define members __nonzero__() and __len__()), it is secure to use the same semantics as the null-coalescing operator.

如果您使用变量s来保存对类实例或无实例的引用(只要您的类没有定义成员__nonzero__()和__len__())),那么使用与null-coalescing操作符相同的语义是安全的。

In fact, it may even be useful to have this side-effect of Python. Since you know what values evaluates to false, you can use this to trigger the default value without using None specifically (an error object, for example).

实际上,使用Python的这种副作用可能会很有用。因为您知道什么值计算为false,所以可以使用它来触发默认值,而不是使用None(例如,错误对象)。

In some languages this behavior is referred to as the Elvis operator.

在某些语言中,这种行为被称为猫王的操作符。

#2


42  

strictly,

严格来说,

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

otherwise s=False will become "default value", which may not be what was intended.

否则s=False将变成“默认值”,这可能不是预期的。

If you want to make this shorter, try

如果你想缩短这个时间,试试吧。

def notNone(s,d):
    if s is None:
        return d
    else:
        return s

other = notNone(s, "default value")

#3


26  

Here's a function that will return the first argument that isn't None:

这里有一个函数,它会返回第一个不是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() might needlessly iterate over all the arguments even if the first argument is not None, so you can also use this version:

reduce()可能不必要地遍历所有的参数,即使第一个参数不是None,所以您也可以使用这个版本:

def coalesce(*arg):
  for el in arg:
    if el is not None:
      return el
  return None

#4


2  

In addition to Juliano's answer about behavior of "or": it's "fast"

除了Juliano对“或”行为的回答:“快”

>>> 1 or 5/0
1

So sometimes it's might be a useful shortcut for things like

所以有时候它可能是一个有用的捷径。

object = getCachedVersion() or getFromDB()

#5


-3  

The two functions below I have found to be very useful when dealing with many variable testing cases.

在处理许多变量测试用例时,我发现下面的两个函数非常有用。

def nz(value, none_value, strict=True):
    ''' This function is named after an old VBA function. It returns a default
        value if the passed in value is None. If strict is False it will
        treat an empty string as None as well.

        example:
        x = None
        nz(x,"hello")
        --> "hello"
        nz(x,"")
        --> ""
        y = ""   
        nz(y,"hello")
        --> ""
        nz(y,"hello", False)
        --> "hello" '''

    if value is None and strict:
        return_val = none_value
    elif strict and value is not None:
        return_val = value
    elif not strict and not is_not_null(value):
        return_val = none_value
    else:
        return_val = value
    return return_val 

def is_not_null(value):
    ''' test for None and empty string '''
    return value is not None and len(str(value)) > 0

#1


262  

other = s or "some default value"

Ok, it must be clarified how the or operator works. It is a boolean operator, so it works in a boolean context. If the values are not boolean, they are converted to boolean for the purposes of the operator.

好的,必须弄清楚or运算符是如何工作的。它是一个布尔运算符,所以它在布尔上下文中工作。如果值不是布尔值,则为操作符的目的将其转换为布尔值。

Note that the or operator does not return only True or False. Instead, it returns the first operand if the first operand evaluates to true, and it returns the second operand if the first operand evaluates to false.

注意or操作符不仅返回True或False。相反,如果第一个操作数计算为true,则返回第一个操作数,如果第一个操作数计算为false,则返回第二个操作数。

In this case, the expression x or y returns x if it is True or evaluates to true when converted to boolean. Otherwise, it returns y. For most cases, this will serve for the very same purpose of C♯'s null-coalescing operator, but keep in mind:

在这种情况下,如果表达式x或y为真,则返回x;如果它为真,则返回x;否则,它将返回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"

If you use your variable s to hold something that is either a reference to the instance of a class or None (as long as your class does not define members __nonzero__() and __len__()), it is secure to use the same semantics as the null-coalescing operator.

如果您使用变量s来保存对类实例或无实例的引用(只要您的类没有定义成员__nonzero__()和__len__())),那么使用与null-coalescing操作符相同的语义是安全的。

In fact, it may even be useful to have this side-effect of Python. Since you know what values evaluates to false, you can use this to trigger the default value without using None specifically (an error object, for example).

实际上,使用Python的这种副作用可能会很有用。因为您知道什么值计算为false,所以可以使用它来触发默认值,而不是使用None(例如,错误对象)。

In some languages this behavior is referred to as the Elvis operator.

在某些语言中,这种行为被称为猫王的操作符。

#2


42  

strictly,

严格来说,

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

otherwise s=False will become "default value", which may not be what was intended.

否则s=False将变成“默认值”,这可能不是预期的。

If you want to make this shorter, try

如果你想缩短这个时间,试试吧。

def notNone(s,d):
    if s is None:
        return d
    else:
        return s

other = notNone(s, "default value")

#3


26  

Here's a function that will return the first argument that isn't None:

这里有一个函数,它会返回第一个不是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() might needlessly iterate over all the arguments even if the first argument is not None, so you can also use this version:

reduce()可能不必要地遍历所有的参数,即使第一个参数不是None,所以您也可以使用这个版本:

def coalesce(*arg):
  for el in arg:
    if el is not None:
      return el
  return None

#4


2  

In addition to Juliano's answer about behavior of "or": it's "fast"

除了Juliano对“或”行为的回答:“快”

>>> 1 or 5/0
1

So sometimes it's might be a useful shortcut for things like

所以有时候它可能是一个有用的捷径。

object = getCachedVersion() or getFromDB()

#5


-3  

The two functions below I have found to be very useful when dealing with many variable testing cases.

在处理许多变量测试用例时,我发现下面的两个函数非常有用。

def nz(value, none_value, strict=True):
    ''' This function is named after an old VBA function. It returns a default
        value if the passed in value is None. If strict is False it will
        treat an empty string as None as well.

        example:
        x = None
        nz(x,"hello")
        --> "hello"
        nz(x,"")
        --> ""
        y = ""   
        nz(y,"hello")
        --> ""
        nz(y,"hello", False)
        --> "hello" '''

    if value is None and strict:
        return_val = none_value
    elif strict and value is not None:
        return_val = value
    elif not strict and not is_not_null(value):
        return_val = none_value
    else:
        return_val = value
    return return_val 

def is_not_null(value):
    ''' test for None and empty string '''
    return value is not None and len(str(value)) > 0