Использование IF, AND, OR вместе с операндом EQUAL вместе в Python
Я пытаюсь создать функцию, в которой заданное значение (переданное в виде строки) проверяется, чтобы увидеть, является ли число цифр 4 или 6, и что это число.
Мой первый импульс должен был пойти с этим кодом:
def number(x):
if (len(x) == (4 or 6)) and x.isdigit():
print "True"
else:
print "False"
Этот код выше только проходит первый тест ниже... Я не понимаю, почему он проходит это, но ни один из других тестов:
number("1234")
Только когда я отделю функции len(), он будет работать правильно.
def number(x):
if (len(x) == 4 or len(x) == 6) and x.isdigit():
print "True"
else:
print "False"
## Checks
number("1234")
number("123456")
number("abcd")
number("abcdef")
number("1")
number("a")
Приведенный выше код проходит все тесты.
Итак, мои вопросы:
- Что тут происходит?
- Есть ли способ написать более чистый код для этого?
Спасибо за помощь!
** Не повторяющийся вопрос, потому что, хотя этот вопрос имеет те же основные понятия, касающиеся булевых операторов, сама проблема отличается из-за использования len(), isdigit() и дополнительного вопроса о том, как лучше его улучшить (кто-то прокомментировал использование возврата). Определенно добавляет другую перспективу к другому вопросу, хотя.
6 ответов
Это помогает изучить логику этой строки:
if (len(x) == (4 or 6)):
(4 or 6)
предложение содержит логический or
короткое замыкание. Значение 4
верно, поэтому он оценивается и возвращается ==
реляционное сравнение.
Способ, которым or
работает то, что его левая часть вычисляется для логической истины, и ее значение возвращается, если оно истинно. Если левая часть не является логическим значением true, тогда правая часть вычисляется и возвращается ее значение.
Потому что левая сторона 4 or ...
верно в логическом смысле, правая часть никогда не оценивается. Python даже не смотрит в прошлое 4 or
, Если левое значение было ложным (например, 0), то правая часть or
будет оцениваться.
Чтобы увидеть это в действии, попробуйте print 4 or 6
, Выход будет 4.
Так как 4 является жестко закодированным истинным значением, ваше сравнение семантически такое же, как if (len(x) == 4)
- то есть, поскольку 4 истинно, 6 никогда не оценивается.
Я полагаю, что вы действительно хотите знать, если len(x)
4 или 6. Вы можете поместить это в код несколькими способами:
if(len(x) == 4 or len(x) == 6 ...
if(len(x) in (4,6) ...
Вы можете использовать in
Оператор вроде так:
def number(x):
if len(x) in (4, 6) and x.isdigit():
print "True"
else:
print "False"
где in
проверяет содержание в данном контейнере. Обратите внимание, что 4 or 6
сами по себе оценивать что-то нежелательное, вот почему ваш первый сегмент кода терпит неудачу. Вы можете проверить это на оболочке Python:
>>> 4 or 6
4
Вы, вероятно, хотели написать
if (len(x) in (4, 6)) and x.isdigit():
Вместо
if (len(x) == (4 or 6)) and x.isdigit():
Короткий ответ: len(x) in [4, 6]
или же len(x) == 4 or len(x) == 6
,
"или" является логическим или логическим выбором. (4 или 6) гарантированно разрешает ненулевое (истинное) значение. В этом случае он разрешается до 4, поэтому ваш тестовый пример проходит.
Я пойду вперед и отвечу
Есть ли способ написать более чистый код для этого?
Да. Вернуть логическое значение, а не печатать строку.
def number(x):
return len(x) in {4, 6} and x.isdigit()
print(number("1234")) # True
Тогда просто используйте ваш метод в операторе if без сравнения строк.
Беда в вашем or
заявление.
Любое значение больше единицы оценивается как True
когда вы положите его в условный. Так (4 or 6)
всегда будет решаться на истину.
Вы могли бы использовать in
утверждение выше или вы могли бы просто использовать два ==
"S:
if (len(x) == 4 or len(x) == 6) and x.isdigit()
Это немного словеснее, мне легче читать.