我的问题是我想编写一个函数newlist
,该函数以数字list
作为参数。然后,它将基于该参数返回一个新列表。新列表包含与原始列表相同的值,直到达到数字7。
有效的代码:
def newlist(mylst):
newlst = []
idx = 0
while (idx < len(mylst)) and (mylst[idx] != 7):
newlst.append(mylst[idx])
idx += 1
return newlst
现在,当我像这样切换and
语句的两边时:
while (mylst[idx] != 7) and (idx < len(mylst)):
它告诉我这是错误的,并且在将列表作为参数传递时,索引为
超出范围。我的问题是,为什么它与我开始的and
语句的哪一边有所不同?我以为布尔值只有在两个语句均为True时才为True,而与顺序无关?
答案 0 :(得分:1)
差异是由于and
运算符使用短路这一事实造成的。这意味着,如果第一个操作数为false,则不会计算第二个操作数。
以下:
(idx < len(mylst)) and (mylst[idx] != 5)
第一个操作数是(idx < len(mylst))
。这将检查idx
是否在范围内。如果是,那么将评估第二个操作数,该操作数使用idx
作为mylst
的索引。但是,如果不是,则评估停止,表达式的结果为False
。这样,它将永远不会超出范围,因为第一个操作数会保护第二个操作数的值。
第二个版本是:
(mylst[idx] != 5) and (idx < len(mylst))
在这里,操作数是相反的。结果,如果idx
超出范围,它将仍然尝试将其用作mylst
的索引,从而导致错误。
所以这两个版本有很大的不同。在尝试将idx
用作索引之前,第一个版本会安全地检查echo $(htpasswd -nb your-user your-password);
是否在范围内,而第二个版本则不会。