与空列表进行比较时使用“==”运算符是否错误?
Is it wrong to use the "==" operator when comparing to an empty list?
PyCharm (4.0.6) 在我使用 ==
运算符与空列表进行比较时会报错,但在我使用 is
运算符时却不会:
我想这与 PEP 8 有关,但问题是当我使用 is
运算符时,正如 PyCharm 所暗示的那样,我有一个假阴性。这是 iPython shell 中的一个简单示例,表明在这种情况下 ==
运算符似乎更合适,因为 is
运算符 returns 是假阴性:
In[2]: actions = []
In[3]: actions == []
Out[3]: True
In[4]: actions is []
Out[4]: False
有人可以解释为什么 PyCharm 在与空列表进行比较时抱怨 ==
运算符吗?根据 PEP 8,我做错了什么吗?
引用 PEP-8's Programming Recommendations 部分,
For sequences, (strings, lists, tuples), use the fact that empty sequences are false.
Yes: if not seq:
if seq:
No: if len(seq)
if not len(seq)
因为空序列在 Python 中是 Falsy,
>>> bool([])
False
>>> bool(())
False
您可以简单地使用 PEP-8 中提到的 if not
。
注意: 永远不要使用 is
来比较两个值是否相等,因为 is
运算符检查两个对象是否相同, 但 ==
检查两个对象是否相等。
我深入研究了源代码以了解发生了什么。当我们做 a == []
,
>>> dis(compile('if a == []: pass', "string", "exec"))
1 0 LOAD_NAME 0 (a)
3 BUILD_LIST 0
6 COMPARE_OP 2 (==)
9 POP_JUMP_IF_FALSE 15
12 JUMP_FORWARD 0 (to 15)
>> 15 LOAD_CONST 0 (None)
18 RETURN_VALUE
我们正在构建一个新列表,这将是一个非常昂贵的操作,仅供比较。另一方面
>>> dis(compile('if not a: pass', "string", "exec"))
1 0 LOAD_NAME 0 (a)
3 POP_JUMP_IF_TRUE 9
6 JUMP_FORWARD 0 (to 9)
>> 9 LOAD_CONST 0 (None)
12 RETURN_VALUE
我们正在尝试查看当前序列是否为 Truthy。这在内部检查序列的长度是否为零(这只是一个简单的查找,因为列表的长度保存在一个变量中)。如果长度为零,则 if not actions:
将为 Truthy。这里我们没有构造一个新的列表,只是隐式地检查长度,而不是显式地做
if len(actions) == 0:
所以,我猜测 Python 专家建议 if not seq
因为这也可能带来性能优势。
根据 PEP8 文档,您应该使用
For sequences, (strings, lists, tuples), use the fact that empty sequences are false.
Yes: if not seq:
if seq:
No: if len(seq)
if not len(seq)
PyCharm (4.0.6) 在我使用 ==
运算符与空列表进行比较时会报错,但在我使用 is
运算符时却不会:
我想这与 PEP 8 有关,但问题是当我使用 is
运算符时,正如 PyCharm 所暗示的那样,我有一个假阴性。这是 iPython shell 中的一个简单示例,表明在这种情况下 ==
运算符似乎更合适,因为 is
运算符 returns 是假阴性:
In[2]: actions = []
In[3]: actions == []
Out[3]: True
In[4]: actions is []
Out[4]: False
有人可以解释为什么 PyCharm 在与空列表进行比较时抱怨 ==
运算符吗?根据 PEP 8,我做错了什么吗?
引用 PEP-8's Programming Recommendations 部分,
For sequences, (strings, lists, tuples), use the fact that empty sequences are false.
Yes: if not seq: if seq: No: if len(seq) if not len(seq)
因为空序列在 Python 中是 Falsy,
>>> bool([])
False
>>> bool(())
False
您可以简单地使用 PEP-8 中提到的 if not
。
注意: 永远不要使用 is
来比较两个值是否相等,因为 is
运算符检查两个对象是否相同, 但 ==
检查两个对象是否相等。
我深入研究了源代码以了解发生了什么。当我们做 a == []
,
>>> dis(compile('if a == []: pass', "string", "exec"))
1 0 LOAD_NAME 0 (a)
3 BUILD_LIST 0
6 COMPARE_OP 2 (==)
9 POP_JUMP_IF_FALSE 15
12 JUMP_FORWARD 0 (to 15)
>> 15 LOAD_CONST 0 (None)
18 RETURN_VALUE
我们正在构建一个新列表,这将是一个非常昂贵的操作,仅供比较。另一方面
>>> dis(compile('if not a: pass', "string", "exec"))
1 0 LOAD_NAME 0 (a)
3 POP_JUMP_IF_TRUE 9
6 JUMP_FORWARD 0 (to 9)
>> 9 LOAD_CONST 0 (None)
12 RETURN_VALUE
我们正在尝试查看当前序列是否为 Truthy。这在内部检查序列的长度是否为零(这只是一个简单的查找,因为列表的长度保存在一个变量中)。如果长度为零,则 if not actions:
将为 Truthy。这里我们没有构造一个新的列表,只是隐式地检查长度,而不是显式地做
if len(actions) == 0:
所以,我猜测 Python 专家建议 if not seq
因为这也可能带来性能优势。
根据 PEP8 文档,您应该使用
For sequences, (strings, lists, tuples), use the fact that empty sequences are false.
Yes: if not seq:
if seq:
No: if len(seq)
if not len(seq)