Оценка операторов сравнения в Python, которые ведут себя неожиданно

В этом семестре я прохожу вводный курс по Python (используя 3.4) и недавно наткнулся на упражнение о приоритете операторов и использовании круглых скобок, чтобы выражение оценивалось как истинное.

Точный вопрос:

Add a single pair of parentheses to the expression so that it evaluates to true.
1 < -1 == 3 > 4

Я предположил, что правильный ответ будет таким:

1 < -1 == (3 > 4)

Учитывая, что все операторы сравнения имеют один и тот же уровень приоритета, они должны оцениваться слева направо, поэтому он должен оцениваться как таковой:

1 < -1 == (3 > 4) 
1 < -1 == False
False == False
True

Но когда я запускаю код, он все равно возвращает false. Я видел этот вопрос приоритет операторов сравнения в Python и C/C++ и результат этого выражения мне понятен; но в этом случае я принудительно оценил последнее утверждение перед оценкой остальной части выражения, поэтому я не понимаю, почему я все еще получаю неправильный ответ.

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


person Terry Chern    schedule 30.01.2015    source источник
comment
Вы понимаете часть этого ответа о цепочке сравнения? Этот ответ объясняет, как последовательности операторов сравнения не работают в соответствии с простым порядком приоритета, а объединяются в несколько сравнений с помощью and.   -  person BrenBarn    schedule 30.01.2015
comment
@BrenBarn Я думал, что понял это, но, думаю, я не понимаю всех последствий. Я попытаюсь написать это с цепочкой и посмотрю, смогу ли я лучше понять, где я ошибаюсь.   -  person Terry Chern    schedule 30.01.2015
comment
@BrenBarn Хорошо, поэтому фактическое оцениваемое утверждение равно 1 ‹ -1 и -1 == (3 › 4), что приводит к окончательной оценке False и False, что приводит к False. Мне нужно будет поиграть с ним еще немного, я думаю. Спасибо за помощь!   -  person Terry Chern    schedule 30.01.2015
comment
@TerryChern: рискую выдать спойлер, я не уверен, что тот, кто написал эту головоломку, не был также смущен цепочкой сравнений в Python .. (или что нет опечатки, и предполагается, что последний > быть <..)   -  person DSM    schedule 30.01.2015
comment
@DSM Да, я смотрю на лист заданий, предоставленный моим университетом, и они отмечают, что для этой конкретной проблемы мы можем использовать две пары скобок.   -  person Terry Chern    schedule 30.01.2015
comment
Да, я не думаю, что есть способ решить эту конкретную задачу только с одним набором скобок.   -  person BrenBarn    schedule 30.01.2015
comment
Я использовал цикл и eval, чтобы вручную вставить круглые скобки во все возможные места, чтобы увидеть, не упустил ли я что-то, и не нашел решений для 1 < -1 == 3 > 4, хотя 1 < -1 == 3 < 4 имел (1 < -1 == 3) < 4.   -  person DSM    schedule 30.01.2015
comment
Ну, во всяком случае, это будет интересный вопрос, который стоит обсудить со студентами!   -  person Terry Chern    schedule 30.01.2015
comment
@BrenBarn Если вы хотите отправить ответ, я был бы рад принять его как правильный (указав на цепочку), в противном случае я продолжу и приму ответ Имрана, поскольку это вывод, к которому я пришел. Upvotes все вокруг, хотя за помощь!   -  person Terry Chern    schedule 30.01.2015
comment
@DSM, твой цикл оценивал 1 < -(1 == 3 > 4)? У меня нет, но это не имеет значения — это тоже False.   -  person Robᵩ    schedule 30.01.2015
comment
@Robᵩ: да, потому что я просто вставлял во все позиции строки, а затем ловил TypeErrors и SyntaxErrors.   -  person DSM    schedule 30.01.2015


Ответы (4)


Задача доказуемо невыполнима. Рассмотрим эти три случая:

  1. Непосредственно перед -1 есть открытая скобка.

  2. Между - и 1 есть открытая скобка.

  3. В любом другом месте есть открытый парен.

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

В первом случае у нас есть 1 < ( ... ), где многоточие — логическое выражение. Поскольку 1 не меньше True или False, все выражение равно False.

Во втором случае у нас есть 1 < -( ...), где многоточие — логическое выражение. Поскольку 1 не меньше ни -True, ни -False, все выражение равно False.

В третьем случае у нас есть 1 < -1 == .... Поскольку все стороны выражения связанных операторов должны быть истинными, а 1 < -1 — ложным, все выражение равно False.

Итак, во всех возможных случаях результат False.

person Robᵩ    schedule 30.01.2015
comment
Это отличный способ приблизиться к этому; намного лучше, чем вручную добавлять скобки и проверять каждое решение (хотя DSM применил гораздо более умный метод автоматизации). Принимая это как правильный ответ, поскольку он прямо отвечает на мой вопрос. - person Terry Chern; 30.01.2015
comment
Справедливости ради, вы на самом деле не задавали вопрос, поэтому сложно сказать, кто на него ответил, а кто нет. - person Robᵩ; 30.01.2015
comment
Ну, в конце я спросил, какой правильный ответ, и правильный ответ — его нет. - person Terry Chern; 30.01.2015

3>4 дает False. -1 == False дает False. 1 < False дает False. Следовательно, 1 < -1 == 3 > 4 становится False.

Поставьте правильные скобки, чтобы сделать утверждение семантически правильным.

(1 < -1) == (3 > 4)
person jithinodattu    schedule 30.01.2015
comment
Это решение, которое я искал, но идея состоит в том, чтобы использовать только одну пару скобок. Я не знаю, может быть, в учебнике это просто неправильно. - person Terry Chern; 30.01.2015
comment
@TerryChern Я предполагаю, что учебник был написан для другого языка и преобразован в python (или, по крайней мере, автор был более знаком с чем-то вроде C). Поведение Python в цепных сравнениях очень необычно (и полезно только время от времени). - person sapi; 30.01.2015

Вы на правильном пути, но благодаря цепочке сравнения у вас будет:

1 < -1 == (3 > 4) 
1 < -1 == False
1 < -1 and -1 == False
False and False
False

Обратите внимание, что мы не оцениваем вторую строку слева направо, а связываем два сравнения вместе с помощью и.

Есть только несколько допустимых способов добавить к этому одну пару скобок, поэтому мы можем легко проверить все остальные:

(1 < -1 == 3 > 4)
False #Trivially

(1 < -1) == 3 > 4
False == 3 > 4
False == 3 and 3 > 4
False and False
False

1 < (-1 == 3) > 4
1 < False > 4
1 < False and False > 4
False and False
False

Похоже, у этой проблемы нет ответа!

Редактировать:

Упс! Роб указывает, что мы забыли:

1 < -(1 == 3) > 4
1 < -False > 4
1 < 0 > 4
1 < 0 and 0 > 4
False and False
False
person Imran    schedule 30.01.2015
comment
Да, это вывод, к которому я пришел после прочтения комментария БренБарн; Мне нужно будет продолжать работать над этим, я думаю. - person Terry Chern; 30.01.2015
comment
Хорошо, я вижу, вы, ребята, пришли к тому же выводу! - person Imran; 30.01.2015
comment
Вы пропустили 1 < -(1 == 3) > 4 в своем анализе. - person Robᵩ; 30.01.2015
comment
Если бы я мог принять несколько правильных ответов, я бы выбрал и этот; это в значительной степени процесс, который я прошел, чтобы выяснить, что не было рабочих решений. В то время мне не были полностью ясны последствия цепочки. Я очень ценю помощь, но ответ Роба гораздо более строгий. - person Terry Chern; 30.01.2015

(1 < -1) == (3 > 4)

Ложь == Ложь

Истинный

person w1cked    schedule 17.09.2019
comment
Обратите внимание, что ОП хочет не ответа на решение проблемы, а объяснения того, почему его ответ приводит к неожиданным результатам. - person Alejandro; 17.09.2019
comment
Потому что он забыл скобки в левой части выражения: 1 < -1 == (3 > 4) 1 < -1 == (false) 1 < -1 and -1 == (false) false and false false Имран дал правильное объяснение первой части своего ответа. - person w1cked; 19.09.2019