处理加法中的 None 值

8

我希望对2个整数进行加法运算,这两个整数也可能是空值,具体结果如下:

add(None, None) = None
add(None, b) = b
add(a, None) = a
add(a, b) = a + b

这个问题最符合Python风格、最简洁的表达方式是什么? 到目前为止我只有这样:
def add1(a, b):
    if a is None:
        return b
    elif b is None:
        return a
    else:
        return a + b

或者

def add2(a, b):
    try:
        return a + b
    except TypeError:
        return a if a is not None else b

有没有更简单的方法实现它?

1
两个数字都可以是 int 类型或 None。在这个改变之后,它会错误地返回 None,当输入是 (0, None) 时。 - michailgames
3个回答

13

这是相当紧凑的,可以处理不同数量的术语:

def None_sum(*args):
    args = [a for a in args if not a is None]
    return sum(args) if args else None 

我认为这是一般的答案,非常适合这种问题。所以我赞同这个观点。 - Peter Majko

11

用布尔逻辑:

这里有一个Pythonic方法,使用延迟 or

def add(a, b):
    return (a or 0) + (b or 0)

使用过滤器

对于任意数量的加数,您可以使用filtersum

def add(*p):
    return sum(filter(None, p))

print(add(3))
# 3
print(add(3, 5))
# 8
print(add(3, 5, 7))
# 15
print(add(3, None))
# 3
print(add(None))
# 0
print(add(None, 0))
# 0

出现异常

请注意之前的实现会返回add(None, None)的结果为0。这是一个空和的预期数学结果。

返回None是令人惊讶的,并且可能导致当您使用add的输出时出现TypeError

当用户没有输入任何有效的加数时,实现期望的行为的一种方法是抛出异常:

def add(*p):
    summands = list(filter(None, p))
    if not summands:
        raise ValueError("There should be at least one defined value.")
    return sum(summands)

print(add(3))
# 3
print(add(3, 5))
# 8
print(add(3, 5, 7))
# 15
print(add(3, None))
# 3
print(add(None, 0))
# 0
print(add(0))
# 0
print(add(None))
# ValueError: There should be at least one defined value
print(add())
# ValueError: There should be at least one defined value

1
我知道当期望add(None, None)为0时可以这样写,但这不是我想要的。 - michailgames
1
@michailgames:只是好奇,你为什么需要它? - Eric Duminil
我需要展示用户提供的数字之和(可能填写或未填写),如果至少有一个数字被提供,则采取不同的行动,当没有数字被提供时(这与0不同)。 - michailgames
@michailgames:我建议在那种情况下抛出异常。 - Eric Duminil
1
一般来说,我同意抛出异常。但有时候(例如当你需要先处理大量数据,然后从中生成某种摘要时),通过异常中断流程不是一个选项。 - michailgames
@michailgames:谢谢您的解释,看起来很有道理。 - Eric Duminil

2

试试这个

def add(a,b):
    a = 0 if not a else a
    b = 0 if not b else b
    return a+b

3
无法满足 add(None, None) = None。 - michailgames

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接