Оценка на операторите за сравнение в 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 Ако искате да изпратите отговор, ще се радвам да го приема като правилен (посочвайки веригата), в противен случай ще продължа и ще приема този на Имран, тъй като това е заключението, до което стигнах. Все пак гласува „за“ за помощта!   -  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 == .... Тъй като всички крака на израз от верижни оператори трябва да са True и тъй като 1 < -1 е False, целият израз е 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
Да, това е заключението, до което стигнах, след като прочетох коментара на BrenBarn; Предполагам, че ще трябва да продължа да работя по въпроса. - person Terry Chern; 30.01.2015
comment
Добре, виждам, че сте стигнали до същото заключение! - person Imran; 30.01.2015
comment
Пропуснахте 1 < -(1 == 3) > 4 в анализа си. - person Robᵩ; 30.01.2015
comment
Ако можех да приема няколко верни отговора, бих избрал и този; това е почти процесът, през който минах, за да разбера, че няма работещи решения. Последиците от верижното свързване не ми бяха напълно ясни по това време. Наистина оценявам помощта, но отговорът на Robᵩ е много по-строг. - person Terry Chern; 30.01.2015

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

False == False

Вярно

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