Python - 具有分组和无分组的逻辑评估顺序

时间:2017-07-17 19:47:19

标签: python

任何人都可以解释当False优先于None或None优于False时的行为

1 in None or []  

Traceback (most recent call last):
  File "C:\ProgramData\Anaconda2\lib\site-packages\IPython\core\interactiveshell.py", line 2881, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-4-0f48647a1d09>", line 1, in <module>
    1 in None or []
TypeError: argument of type 'NoneType' is not iterable
1 in (None or [])
Out[5]: False

1 in (None or [1])
Out[6]: True

1 in [1] or None
Out[15]: True

1 in []
Out[17]: False

Below one returns None
1 in [] or None
**Returns None ** 

为什么以下返回异常但是返回上面的无

1 in None  
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda2\lib\site-packages\IPython\core\interactiveshell.py", line 2881, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-21-71e8d29ac0d2>", line 1, in <module>
    1 in None
TypeError: argument of type 'NoneType' is not iterable

4 个答案:

答案 0 :(得分:2)

让我们依次看看每一个:

1 in None or []    -> (1 in None) or [] -> (Error)
1 in (None or [])  -> 1 in []           -> False
1 in (None or [1]) -> 1 in [1]          -> True
1 in [1] or None   -> True or None      -> True
1 in []                                 -> False
1 in [] or None    -> False or None     -> None (not printed)

有几个要点可以理解:

  • 评估顺序是从左到右
  • x in y优先于y or z
  • x or y评估为x if x else y
  • None结果从未在交互式shell中打印

答案 1 :(得分:2)

(经过一些编辑后,这里有一些注意事项可以帮助解决方法/解释)

注1 - 如何在没有

的情况下将None变为False

使用not运算符将None转换为布尔值True。同样,使用not notNone转换为布尔值False

In [4]: a = 1 in [] or None

In [5]: print(a)
None

In [6]: print(not a)
True

In [7]: print(not not a)
False

注2 - 如何使用bool()

将None转换为False

根据下面的评论(@tobias_k),我们实际上可以使用较短的代码将None直接转换为False

In [8]: print(bool(None))
False

注3 - 在运算符中仅适用于可迭代数据类型

in运算符仅适用于iterable的数据结构。我们可以检查数据结构是否可以使用hasattr()函数进行迭代。

例如,listtuplerange都是可迭代的:

In [31]: hasattr([], '__iter__')
Out[31]: True

In [32]: hasattr((), '__iter__')
Out[32]: True

In [33]: hasattr(range(0), '__iter__')
Out[33]: True

由于这些是可迭代的,in运算符可以正常工作(即不会抛出错误):

In [34]: 1 in []
Out[34]: False

In [35]: 1 in ()
Out[35]: False

In [36]: 1 in range(0)
Out[36]: False

Noneintbool等数据类型不是可迭代的:

In [40]: hasattr(None, '__iter__')
Out[40]: False

In [41]: hasattr(1, '__iter__')
Out[41]: False

In [42]: hasattr(True, '__iter__')
Out[42]: False

In [43]: hasattr(False, '__iter__')
Out[43]: False

in运算符因此会针对这些非可迭代类型抛出错误。 e.g。

In [44]: 1 in None
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-44-71e8d29ac0d2> in <module>()
----> 1 1 in None

TypeError: argument of type 'NoneType' is not iterable

In [45]: 1 in 1
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-45-36200f7947c7> in <module>()
----> 1 1 in 1

TypeError: argument of type 'int' is not iterable

In [47]: 1 in False
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-47-0ba098e6e3c7> in <module>()
----> 1 1 in False

TypeError: argument of type 'bool' is not iterable

In [48]: 1 in True
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-48-5e7fb522bdca> in <module>()
----> 1 1 in True

TypeError: argument of type 'bool' is not iterable

注4 - 理解“或”运算符

了解如何评估以下内容:

  • 1 in [] or None - &gt; (1 in []) or None - &gt; False or None - &gt; (短路返回非假的)None

  • 1 in [1, 2, 3] or None - &gt; (1 in [1, 2, 3]) or None - &gt; True or None - &gt; (短路返回非假的)True

  • 1 in None or [] - &gt; (error!!!) or [] - &gt; (投掷的短路)error!!!

  • 1 in None or [1, 2, 3] - &gt; (error!!!) or [1, 2, 3] - &gt; (投掷的短路)error!!!

请注意,1 in None始终会返回错误。如前面的注释3中所述,in运算符仅适用于iterable,而None不是可迭代的。因此错误。 (用print()打印出上述测试以使其可视化)

对于两个错误的情况,您可能需要考虑添加一些括号来强化逻辑(正如我刚刚在@tobias_k的答案中读到的那样)。例如

  • 1 in None or []更改为1 in (None or []) - 这将评估为1 in [](绕过None),现在应返回False(按预期方式)
  • 1 in None or [1, 2, 3]更改为1 in (None or [1, 2, 3]) - 这将评估为1 in [1, 2, 3](再次绕过None),现在应该返回True(按预期方式)< / LI>

答案 2 :(得分:1)

打印结果以查看它:

>>> print(1 in [] or None)
None
  • None不是可迭代的,你需要一个可迭代的东西 in 运算符,这就是你得到错误TypeError的原因: “NoneType”类型的参数不可迭代。

    空列表 是可迭代的。可迭代是一个能够对象 一次返回一个成员。

  • False不会优先于None,也不会优先于False。发生这种情况是因为这就是操作员的工作方式。

    >>> False or 5
    5
    

所以

    >>> print(False or None)
    None

答案 3 :(得分:0)

您的代码从左到右进行评估。所以1 in []是假的。因此,在FalseNone之间,您会获得None

>>> False or None
>>> False or False
False
>>> None or False
False

也许更清楚一点。这是它评估它的方式。

1 in []或None

第1步:在[]中评估1我们有False

第2步:比较FalseNone。由于第一个元素是False,我们只得到第二个值。