Python If语句顺序

Python If语句顺序,python,operator-precedence,Python,Operator Precedence,我当时正在使用Python进行一些CodingBat练习,直到我偶然发现我提出的解决方案存在问题 这个练习的链接是 我尝试使用以下代码解决此问题: def alarm_clock(day, vacation): if vacation and day == 0 or day == 6: return "off" elif vacation and day != 0 and day != 6: return "10:00" if vacati

我当时正在使用Python进行一些CodingBat练习,直到我偶然发现我提出的解决方案存在问题

这个练习的链接是

我尝试使用以下代码解决此问题:

def alarm_clock(day, vacation):
    if vacation and day == 0 or day == 6:
        return "off"
    elif vacation and day != 0 and day != 6:
        return "10:00"
    if vacation == False and day == 0 or day == 6:
        return "10:00"
    elif vacation == False and day != 0 or day != 6:
        return "7:00"

当第6天休假为假时,它返回“off”而不是“10:00”。你能在这里分享一些光线吗?前一个If语句是否计算为“10:00”值?

在Python中,逻辑
的优先级低于
的优先级

所以在这里排队

 if vacation and day == 0 or day == 6:
 if vacation and (day == 0 or day == 6):
只要
day==6
,整个语句都是正确的

所以正确的答案是

评价像

(vacation and day == 0) or day == 6
因此,如果
day==6
您的then子句将进行计算

你可能会想要

vacation and (day == 0 or day == 6)

优先于
。 因此,改变:

if vacation and day == 0 or day == 6:

或者更好、更地道的英语,比如:

if vacation and day in [0, 6]:
所以我会让它看起来像这样,更具可读性

weekend = [0, 6]
def alarm_clock(day, vacation):
  if vacation:
    return day in weekend and "off" or "10:00"
  else:
    return day in weekend and "10:00" or "7:00"

其他人已经指出了逻辑运算符的优先级。也许你可以考虑重构你的条件有点像这样(IMHO更准确地反映决策树):

阐述dimo414的评论:

weekend = day in (0, 6)
if vacation:
    if weekend:
         return "off"
    else:
         return "10:00"
else:
     if weekend:
         return "10:00"
     else:
         return "7:00"
甚至:

weekend = day in (0, 6)
if vacation:
    return "off" if weekend else "10:00"
else:
    return "10:00" if weekend else "7:00"

我认为这里最清晰的解决方案是只命名中间值:

weekend = day == 0 or day == 6
现在,无论您是否让事情按原样结构化:

def alarm_clock(day, vacation):
     if vacation and weekend:
         return "off"
     elif vacation and weekday:
         return "10:00"
     elif not vacation and weekend:
         return "10:00"
     elif not vacation and not weekend:
         return "7:00"
…或将其重构为嵌套的
if
语句:

def alarm_clock(day, vacation):
     if vacation:
         if weekend:
             return "off"
         else:
             return "10:00"
     else:
         if weekend:
             return "10:00"
         else:
             return "7:00"
…或在更高的逻辑级别对其进行重构:

def alarm_clock(day, vacation):
     if vacation and weekend:
         return "off"
     elif vacation or weekend:
         return "10:00"
     else:
         return "7:00"
…发生的事情马上就显而易见了,而这个问题根本就不可能出现

它还避免了另一个非常常见的错误,即人们将
not
的组合只进行了一半,而当你的意思是
不是a和不是b时,你会得到
不是a和b


而且,如果您以后决定在一个从周一开始计算周数而不是从周日开始计算周数的国家运行代码,那么您只需更改一行代码而不是四行代码(四行代码几乎足以保证其中一行代码出错……).

从技术上讲,它们是逻辑运算符,不是按位的。@AlbusShin:这不是固定的;您仍然在谈论“按位和”。作为旁注,您不应该使用
vacation==False
;只需使用
而不是休假
。(有些人认为,
==False
是好的,但是(a)他们错了,(b)他们希望你在另外两种情况下使用
vacation==True
,而不仅仅是
vacation
,以及(c)他们错了。:)此外,使用嵌套语句可能更容易考虑这一点。首先,
如果休假:
否则:
。然后,在每一天中,
如果天==0或天==6:
否则:
。这意味着10行代码而不是8行,但它们更短,更明显,更难出错(特别是,您的错误永远不会出现这种情况)。或者,或者,执行
weekday=day==0或day==6
,然后您可以编写
假期和工作日
假期和非工作日
不是假期和工作日
不是假期和工作日
,这可能更具可读性。为什么我总是认为它是完全相反的。。。无论如何,谢谢你的快速回答@user3124364:因为任何阅读任何语言文档中“更高优先级”或“更受约束”或几乎任何其他描述的人都不知道这实际上意味着什么方向。如果你写了一个解析器,或者在你的生活中被这个bug咬了足够多的时间,最终它对你来说会变得很明显,你也可以写一些让新手感到困惑的文档更好的办法是,将
(0,6)
元组存储在一个变量中,然后你可以说
周末的一天
或类似的话。答案很好。我(非常个人)觉得唯一不方便的是你的最后一段代码。当你有4个案例(周末与否,假期与否)时,我更愿意写出所有四个案例,即使其中两个结果相同(或者n个案例有m个结果)。问题在于
elif
是一个隐藏的
not(假期和周末)和(假期或周末)
,不太容易阅读(正如他们所说,代码的阅读频率比编写频率高)。尤其是“显而易见”的部分在这里横穿地狱。@Hyperboreus:我的观点是,如果你使用一个命名良好的变量而不是复制和粘贴条件,无论你如何构造
if
s,都不会因为优先级问题而使条件出错。因此,我展示了尽可能多的构建
if
s`的方法,而不去尝试哪一种更好或更糟。
def alarm_clock(day, vacation):
     if vacation and weekend:
         return "off"
     elif vacation and weekday:
         return "10:00"
     elif not vacation and weekend:
         return "10:00"
     elif not vacation and not weekend:
         return "7:00"
def alarm_clock(day, vacation):
     if vacation:
         if weekend:
             return "off"
         else:
             return "10:00"
     else:
         if weekend:
             return "10:00"
         else:
             return "7:00"
def alarm_clock(day, vacation):
     if vacation and weekend:
         return "off"
     elif vacation or weekend:
         return "10:00"
     else:
         return "7:00"