首页 > 解决方案 > 为什么这些带有“和”的语句的顺序即使带有括号也会改变输出?

问题描述

所以我正在解决 Codecademy 上循环的一些代码挑战。一个特别的问题让我很烦恼。这是根据 Codecademy 的设置:

编写一个名为 delete_starting_evens() 的函数,它有一个名为 lst 的参数。该函数应该从 lst 的前面删除元素,直到列表的前面不是偶数。然后该函数应返回 lst。例如,如果 lst 从 [4, 8, 10, 11, 12, 15] 开始,那么 delete_starting_evens(lst) 应该返回 [11, 12, 15]。即使列表中的每个元素都是偶数,也要确保您的函数正常工作!

现在这段代码工作正常,正如我所料:

def delete_starting_evens(lst):
  while (len(lst) > 0) and (lst[0] % 2 == 0):
    lst.pop(0)
  return lst

print(delete_starting_evens([4, 8, 10, 11, 12, 15]))
print(delete_starting_evens([4, 8, 10]))

虽然此代码产生错误,但我不知道为什么:

def delete_starting_evens(lst):
  while (lst[0] % 2 == 0) and (len(lst) > 0):
    lst.pop(0)
  return lst

print(delete_starting_evens([4, 8, 10, 11, 12, 15]))
print(delete_starting_evens([4, 8, 10]))`

错误是:

Traceback (most recent call last):
  File "script.py", line 8, in <module>
    print(delete_starting_evens([4, 8, 10]))
  File "script.py", line 3, in delete_starting_evens
    while (lst[0] % 2 == 0) and (len(lst) > 0):
IndexError: list index out of range

标签: python

解决方案


这就是 的短路行为and

x and y

计算第一个错误操作数并且不计算任何其他操作数,因为结果已经很清楚了。因此,如果x为假,y则不会进行评估,y因此将避免评估引发的任何错误。请参阅文档

这就是为什么你会经常看到:

if lst and lst[0]:  # if lst is empty, lst[0] will not be tried
    # ... 

但不是:

if lst[0] and lst:  # lst[0] raises error before lst is tested
    # ... 

顺便说一句,您的确切用例有一个库函数,即itertools.dropwhile

from itertools import dropwhile

def delete_starting_evens(lst):
    return list(dropwhile(lambda x: not x%2, lst))

推荐阅读