Неправильно ли использовать оператор "==" при сравнении с пустым списком?
PyCharm (4.0.6) жалуется, когда я делаю сравнение с пустым списком, используя ==
оператор, но это не так, когда я использую is
оператор:
Я полагаю, это связано с PEP 8, но проблема в том, что когда я использую is
Оператор, как предполагает PyCharm, у меня есть ложный минус. Вот простой пример в оболочке iPython, чтобы показать, что в этом случае ==
Оператор кажется более подходящим, так как is
Оператор возвращает ложный минус:
In[2]: actions = []
In[3]: actions == []
Out[3]: True
In[4]: actions is []
Out[4]: False
Может кто-нибудь объяснить, почему PyCharm жалуется на ==
оператор при сравнении с пустыми списками? Я делаю что-то не так согласно PEP 8?
2 ответа
Цитирование раздела рекомендаций по программированию PEP-8,
Для последовательностей (строк, списков, кортежей) используйте тот факт, что пустые последовательности являются ложными.
Yes: if not seq: if seq: No: if len(seq) if not len(seq)
Поскольку пустые последовательности являются ложными в Python,
>>> bool([])
False
>>> bool(())
False
Вы можете просто использовать if not
как упоминалось в PEP-8.
Примечание: вы никогда не должны использовать 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
мы пытаемся увидеть, может ли текущая последовательность быть Истиной. Это внутренне проверяет, равна ли длина последовательности нулю (что является простым поиском, поскольку длина списка поддерживается в переменной). Если длина равна нулю, то if not actions:
будет правдой Здесь мы не создаем новый список, но мы просто проверяем длину неявно, а не явно
if len(actions) == 0:
Итак, я предполагаю, что Python Gurus предлагают 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)