这是一个我坚持的功课问题:
你的同学声称编写了一个函数,用一个前两个值替换列表中的每个值(第一个值为0)。例如,如果列表[1,3,7,11]作为参数传递,则该函数应返回[0,2,6,14] - 注意:22不是输出的一部分。这是代码:
def double_preceding(values):
if (values != []):
temp = values[0]
values[0] = 0
for i in range(1, len(values)):
values[i] = 2 * temp
temp = values[i]
分析此功能并重写它以使其按预期工作。
我甚至无法遵循代码所做的事情,有人可以向我解释
答案 0 :(得分:0)
以下是对给定代码的解释,以及我在其中看到的错误:
def double_preceding(values):
if (values != []): # this if checks for an empty list, to avoid exceptions
temp = values[0]
values[0] = 0 # but this line is not indented, so you may get an IndexError anyway
for i in range(1, len(values)): # this loops over all indexes but the first (0)
values[i] = 2 * temp # this replaces the current value with double temp
temp = values[i] # this line however saves the same doubled value as the new temp
因此,我看到的两个错误是对空列表的错误处理,以及赋值代码中的逻辑错误,该错误将导致循环在第一个值之后用列表的原始第一个值乘以2的连续幂来替换值。
解决第二个问题的一个好方法是使用单个语句在循环中完成两个赋值。这是Python可以做的一件很好的事情,许多其他语言都做不到。这是基本版本的样子:
values[i], temp = temp*2, values[i]
逗号是要注意的关键事项。作业右侧的那个会从tuple
和temp*2
中生成values[i]
。左侧的逗号告诉Python解包分配给变量values[i]
和temp
的元组。并按顺序评估这两个部分(首先是右侧的表达式,然后是解包和赋值)。这意味着temp
和values[i]
的“旧”值用于构建元组,并且它们都会在以后重新分配并不重要。
如果我们以这种方式进行分配,我们也可以优雅地解决空列表情况。而不是专门处理第一个值并需要检查以确保values[0]
是一个有效的表达式,为什么不在开始时将temp
设置为0
并让循环处理第一个值以及后来的?这是一个完全固定的功能:
def double_preceeding(values):
temp = 0
for i in range(len(values)): # loop over all indexes, not skipping the first
values[i], temp = temp*2, values[i]
如果values
为空列表,则循环将不执行任何操作,因为len([])
为0且range(0)
本身为空。
示例输出:
>>> L=[]
>>> double_preceeding(L)
>>> L
[]
>>> L=[1, 3, 7, 11]
>>> double_preceeding(L)
>>> L
[0, 2, 6, 14]
答案 1 :(得分:-1)
如果我猜错了程序的缩进。见下面的评论:
<强>代码:强>
def double_preceding(v):
values = v[:] # Make a copy of the list passed as argument
if (values != []): # If list is not empty, store the first value in 'temp'
temp = values[0]
else:
return
v[0] = 0 # Set the first value of the list as '0' (as the problem says it)
for i in range(1, len(values)): # Iterate 'n - 1' times, where n is the length of the list
v[i] = 2 * temp # Set the corresponding value to twice the precedent (the precedent is stored in 'temp')
temp = values[i]
<强>测试强>
v = [1, 3, 7, 11]
double_preceding(v)
print v
<强>输出:强>
[0, 2, 6, 14, 22]