Проверить есть ли в списке два элемента

почему мне выдает YES данная конструкция

d = [1, 2, 3, 4, 5, ]
if 7 and 5 in d:
    print("YES")
else:
    print("NO")

причем если поставить 1 и 9 он будет работать корректно и выдаст NO


Ответы (3 шт):

Автор решения: alex

потому что 7 and 5 in d работает не так как ты думаешь. по сути ты говоришь если 7 это истина и 5 есть в списке, то YES. во втором случае ты считаешь что все корректно, только потому что 9 нет в списке и условие через and) т.е. суть в том что and или or связывают между собой условия, сначала вычисляется выражение слева, потом справа (а может и не вычисляться)

if 7 in d and 5 in d:
  print("Yes")

7 истина потому что не 0. Все что не 0 будет True, а 0 - False.

Тип bool это, кстати, тоже int. Где True это 1, а False это 0. И они легко конвертируются

int(True) == 1
bool(1) is True
bool(7) is True
["false", "true"][True] == "true"

Истинность последовательностей (list, tuple, dict and more) вычисляется через длину. Если длина последовательности больше нуля, то последовательность истинна. Строка это тоже последовательность.

Остальные классы (типы) могут имплементировать __bool__() или __len__() чтобы поддерживать определение истинности.

Порядок вычисления операций при сложных условиях запомнить очень просто. or спотыкается на правде, and - на лжи. Т.е. если в условии or, то пайтон не станет вычислять выражение справа если выражение слева истинно. Ведь все логично, если выражение слева истинно, то нам не нужно больше делать ничего, условие уже удовлетворяется. Тоже самое с and, если условие слева ложно, то условие справа нам не нужно считать. Независимо от результата мы уже знаем по какой ветке пойдет выполнение.

if (True) or (1/0):
    print("Ok")

Этот код не вызовет ошибки, потому что не нужно делить на ноль, так как выражение истинно из-за первого условия.

if (False) and (1/0):
    print("Ok")

Тоже самое. Нам не нужно вычислять второе условие. Которое вызвало бы исключение.

Скобки я указал, чтобы было нагляднее.

→ Ссылка
Автор решения: user421506

Потому что, как сказал alex, Python в следующем коде

if 7:
     #body
определяет цифру 7 как True, как и любые цифры в теле условного оператора if. Ваш компьютер видит код
if 7 and 5 in d:
     print('YES')

как if 7 и if 5 in d, в обеих случаях результат - True. Корректно было бы так:

if 7 in d and 5 in d:
     #body
.
→ Ссылка
Автор решения: insolor

Для проверки пары элементов корректным решением будет

if 7 in d and 5 in d:
    ...

Если элементов больше чем 2-3, можно сделать проверку через функцию all ("все"):

s = [7, 5]
if all(x in d for x in s):
    ...

Т.е. проверяем, что каждый элемент из s входит в список d.

Такое условие примерно соответствует такой функции:

def all_in(s, d):
    for x in s:
        if x not in d:
            return False
    
    return True

Также можно проверять через множества. Оператор < тут проверяет, что все элементы множества слева входят в множество справа (или просто, левое множество входит в правое множество):

s = {7, 5}
if s < set(d):
    ...

Это будет работать только для хэшируемых значений, но при большом количестве элементов будет работать быстрее, чем предыдущий способ (сложность алгоритма O(N) вместо O(N*M))

→ Ссылка