Неправильно ли использовать оператор "==" при сравнении с пустым списком?

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)
Другие вопросы по тегам