这是一个典型的off-by-one 错误(或者,在这种情况下,off-by-4 错误)。
当x
到达时stringlength-4
,x+4
是stringlength
,即过去的结束string
。所以,你需要x < stringlength-4
,不是x < stringlength
。
但是您可能需要考虑重写代码以使用更高级别的抽象,以使这些问题更难遇到并且更容易思考。
首先,而不是这个:
x= 0
while x < stringlength:
# ...
x += 1
只需这样做:
for x in range(stringlength):
然后你可以用这个解决你的问题:
for x in range(stringlength-4):
但让我们更进一步。
如果你对字符串进行切片,你将不会得到IndexError
:
for x in range(len(stringlength)):
a, b, c, d, e = map(int, string[x:x+4])
但是,现在您将ValueError
在拆包中得到一个。但实际上,您无需在此处解压缩为 5 个单独的变量。只需保持序列并将其相乘即可。(你可以用循环来做到这一点,但在我看来,这是少数几个reduce
用 Python 编写东西的最易读的方式之一。)
for x in range(len(stringlength)):
values = map(int, string[x:x+4])
prod = reduce(operator.mul, values)
if prod > largest:
largest = prod
print(largest)
现在不再有错误了——但那是因为您将最后的 4、3、2 和 1 数字相乘。这正是问题所在:您从未决定过那里应该发生什么。
所以,现在,你可以做出明确的决定。您想将它们计为批次,还是跳过它们?
如果您想进一步向前推进,您可以使用 编写滑动窗口分组器函数itertools
,一个版本的行为类似于zip
(当窗口的右边缘超出列表末尾时zip_longest
停止),另一个版本的行为类似于(仅当窗口的左边缘熄灭):
def groupwise(iterable, n):
groups = itertools.tee(iterable, n)
for i, group in enumerate(groups):
next(itertools.islice(group, i, i), None)
return zip(*groups)
def groupwise_longest(iterable, n, fillvalue=None):
groups = itertools.tee(iterable, n)
for i, group in enumerate(groups):
next(itertools.islice(group, i, i), None)
return itertools.zip_longest(*groups, fillvalue=fillvalue)
现在,您可以这样做:
for group_of_five in groupwise_longest(string, 5, 1):
values = map(int, group)
prod = reduce(operator.mul, values)
if prod > largest:
largest = prod
print(largest)
然后,如果您决定最后不比较不完整的组,只需将第一行更改为:
for group_of_five in groupwise(string, 5):
然后您可以将所有工作移到for
循环之外:
groups = groupwise_longest(string, 5, 1)
intgroups = (map(int, group) for group in groups)
prods = (reduce(operator.mul, group) for group in groups)
现在我们有了一系列产品,很明显要找到最高的产品,那就是:
print(max(prods))
例如:
>>> string = '12345678987654321'
>>> groups = groupwise(string, 5)
>>> intgroups = (map(int, group) for group in groups)
>>> prods = (reduce(operator.mul, group) for group in groups)
>>> max(prods)
28224
请注意,您无处可犯一个错误或任何其他“小”错误。当然,你仍然可能得到完全错误的东西,或者只是不知道如何编写它,但至少你的错误将是明显的大错误,更容易调试。