我快速搜索但找不到任何有助于我解决问题的内容。
我正在尝试制作一个程序,该程序需要前5个数字并获取其产品,如果该产品是迄今为止发现的最大数字,则设置为此类。
我的代码是:
string = str(integer)
x = 0
largest = 0
stringlength = len(string)
while x < stringlength:
a = int(string[x])
b = int(string[x+1])
c = int(string[x+2])
d = int(string[x+3])
e = int(string[x+4])
if (a*b*c*d*e > largest):
largest = a*b*c*d*e
print(largest)
x += 1
print(largest)
我排除了整数值本身,但作为参考,它是1000位数。每当我尝试运行此代码时,我得到“IndexError:字符串索引超出范围”。有人可以帮忙吗?
答案 0 :(得分:7)
string = str(integer)
x = 0
largest = 0
stringlength = len(string)
while x < stringlength-4: # going to -5 would be out of rangue
a = int(string[x])
b = int(string[x+1])
c = int(string[x+2])
d = int(string[x+3])
e = int(string[x+4])
if (a*b*c*d*e > largest):
largest = a*b*c*d*e
print(largest)
x += 1
print(largest)
答案 1 :(得分:2)
这是一个经典的off-by-one error(或者,在这种情况下,是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
请注意,无处可出现一个错误或任何其他“小”错误。当然你仍然可以完全错误,或者根本不知道如何写它,但至少你的错误将是明显的大错误,这更容易调试。