Python:验证条件和引发异常的最佳方法

3

你好,我需要验证一个向量是否包含全部为0或1的元素,如果不是则引发异常:

def assert_all_zero_or_one(vector):
    if set(vector)=={0}: return 0
    if set(vector)=={1}: return 1
    raise TypeError

使用此执行

assert_all_zero_or_one([1,1,1]) # return 1
assert_all_zero_or_one([0,0]) # return 0
assert_all_zero_or_one([1,0,1]) # raise TypeError

我不喜欢这个解决方案... 有没有更好的用Python实现的方法?

我不喜欢 if 语句。这是什么意思? - Felix Kling
你为什么要返回0或1?为什么不使用“False”和“True”呢? - S.Lott
@felix:抱歉,英语不是我的母语。“if falls”意味着我不喜欢连续使用if语句。 - nkint
而且 assert_all_zero_or_one([2,2,2]) 也应该引发 TypeError,对吧? - Tim Pietzcker
@Tim:目前我只使用0和1来编写这段代码片段,但如果能够轻松控制任何解决方案将不胜感激。 - nkint
我只是在问,如果输入内容除了0和1之外还包含其他内容,应该发生什么。 - Tim Pietzcker
5个回答

4
我认为您的解决方案很好地传达了您的意图。您也可以这样做:
def assert_all_zero_or_one(vector):
    if set(vector) not in ({0}, {1}): raise TypeError
    return vector[0]

所以你只需建立set(vector)一次,但我认为你的方法更易于理解。


4
这个怎么样?
def assert_all_zero_or_one(vector):
    if all(v==1 for v in vector): return 1
    elif all(v==0 for v in vector): return 0
    else: raise TypeError

我认为这篇文章写得很好。

如果你喜欢简短而神秘:

def assert_all_zero_or_one(vector):
    a, = set(vector)
    return a

虽然这会导致ValueError而不是TypeError。


你的第二个版本在输入 [2,2,2] 时将返回 2 - Tim Pietzcker
啊,没错。如果只有0和1是可能出现的值,那么仍然是可行的。 - Martin Stone
第二个版本的第二行可以改成 try: a, = set(vector) except ValueError: raise TypeError 以引发“好”的错误类型。 - Frédéric Grosshans

3
def allOneOf(items, ids):
    first = items[0]
    if first in ids and all(i==first for i in items):
        return first
    else:
        raise TypeError()

assert_all_zero_or_one = (lambda vector: allOneOf(vector, set([0,1])))

我选择了这个作为正确答案,因为它更通用。但是我使用了马丁·斯通的答案,因为它更加聪明! - nkint

1

你也可以像这样做。

import functools
import operator

def assert_all_zero_or_one(vector):
    if ((functools.reduce(operator.__mul__,vector) == 1) or (functools.reduce(operator.__add__,vector) == 0)):
            return vector[0]
    else:   
        raise TypeError("Your vector should be homogenous")

0
def assert_all_zero_or_one(vector):
    if len(vector) == sum(vector):
        return True
    elif sum(vector) == 0:
        return True
    return False

这应该很好地工作。


1
我刚意识到如果输入是[-1,1]或[2,0]等,这个方法行不通...但你在问题中使用的set方法无论如何都会更快。 - Diarmuid Bourke

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