简体   繁体   English

检查多个变量是否不是None的最pythonic方法是什么?

[英]What is the most pythonic way to check if multiple variables are not None?

If I have a construct like this:如果我有这样的构造:

def foo():
    a=None
    b=None
    c=None

    #...loop over a config file or command line options...

    if a is not None and b is not None and c is not None:
        doSomething(a,b,c)
    else:
        print "A config parameter is missing..."

What is the preferred syntax in python to check if all variables are set to useful values? python 中检查所有变量是否都设置为有用值的首选语法是什么? Is it as I have written, or another better way?是像我写的那样,还是其他更好的方法?

This is different from this question: not None test in Python ... I am looking for the preferred method for checking if many conditions are not None.这与这个问题不同: not None test in Python ...我正在寻找检查许多条件是否不是 None 的首选方法。 The option I have typed seems very long and non-pythonic.我输入的选项似乎很长且非pythonic。

It can be done much simpler, really它可以做得更简单,真的

if None not in (a, b, c, d):
    pass

UPDATE:更新:

As slashCoder has correctly remarked, the code above implicitly does a == None, b == None, etc. This practice is frowned upon.正如 slashCoder 正确评论的那样,上面的代码隐含地做了 a == None、b == None 等。这种做法是不受欢迎的。 The equality operator can be overloaded and not None can become equal to None.相等运算符可以重载,而不是 None 可以变为等于 None。 You may say that it never happens.你可能会说它永远不会发生。 Well it does not, until it does.好吧,它不会,直到它发生。 So, to be on the safe side, if you want to check that none of the objects are None you may use this approach所以,为了安全起见,如果你想检查没有一个对象是 None 你可以使用这种方法

if not [x for x in (a, b, c, d) if x is None]:
    pass

It is a bit slower and less expressive, but it is still rather fast and short.它有点慢且表现力较差,但它仍然相当快和短。

There's nothing wrong with the way you're doing it.你这样做的方式没有任何问题。

If you have a lot of variables, you could put them in a list and use all :如果你有很多变量,你可以把它们放在一个列表中并使用all

if all(v is not None for v in [A, B, C, D, E]):

I know this is an old question, but I wanted to add an answer which I believe is better.我知道这是一个老问题,但我想添加一个我认为更好的答案。

If all elements which have to be checked are hashable, you could use a set instead of a list or tuple.如果必须检查的所有元素都是可散列的,则可以使用集合而不是列表或元组。

>>> None not in {1, 84, 'String', (6, 'Tuple'), 3}

This is much faster than the methods in the other answers.这比其他答案中的方法快得多。

$ python3 -m timeit "all(v is not None for v in [1, 84, 'String', (6, 'Tuple'), 3])"
200000 loops, best of 5: 999 nsec per loop

$ python3 -m timeit "None not in [1, 84, 'String', (6, 'Tuple'), 3]"
2000000 loops, best of 5: 184 nsec per loop

$ python3 -m timeit "None not in (1, 84, 'String', (6, 'Tuple'), 3)"
2000000 loops, best of 5: 184 nsec per loop

python3 -m timeit "None not in {1, 84, 'String', (6, 'Tuple'), 3}"
5000000 loops, best of 5: 48.6 nsec per loop

Another advantage of this method is that it gives you the correct answer even if someone defines the __eq__ method of a class to always return True .此方法的另一个优点是,即使有人将类的__eq__方法定义为始终返回True ,它也会为您提供正确的答案。 (Of course, if they define the __hash__ method to return hash(None) , this method won't work. But nobody should do that, because it would defeat the purpose of defining a hash.) (当然,如果他们定义__hash__方法return hash(None) ,这个方法将不起作用。但没有人应该这样做,因为它会__hash__定义散列的目的。)

class my_int(int):
    def __init__(self, parent):
        super().__init__()

    def __eq__(self, other):
        return True

    def __hash__(self):
        return hash(super())

print(all(v is not None for v in [1, my_int(6), 2])) # True (correct)
print(None not in [1, my_int(6), 2])                 # False (wrong)
print(None not in (1, my_int(6), 2))                 # False (wrong)
print(None not in {1, my_int(6), 2})                 # True (correct)

For the specific case presented by the OP对于 OP 提出的特定案例

if not all([a, b, c])

will be enough.就足够了。

all([a, b, c])

evaluates to False if any parameter is missing.如果缺少任何参数,则计算结果为 False。

Writing a separate answer as I do not know how to format code when added as a comment.写一个单独的答案,因为我不知道在作为评论添加时如何格式化代码。

Eternal_N00B's solution is not same as Daniel Roseman's solution. Eternal_N00B 的解决方案与 Daniel Roseman 的解决方案不同。 Consider for example:考虑例如:

>>> all(v is not None for v in [False])
True
>>> all([False])
False
x = 'a'
y = 'b'
z = 'c'

if all(item is not None for item in [x, y, x]):
    print('Multiple variables are NOT None')
else:
    print('At least one of the variables stores a None value')

Complementing Daniel Roseman's answer, I think: 我认为,补充丹尼尔罗斯曼的答案:

if all([a,b,c,d]):

is cleaner 更清洁

Since all() built-in function already iterates over the list checking for None values 由于all()内置函数已遍历列表检查None

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM