简体   繁体   English

“'生成器' object 不可下标”错误

[英]"'generator' object is not subscriptable" error

Why am I getting this error, from line 5 of my code, when attempting to solve Project Euler Problem 11?为什么我在尝试解决 Project Euler 问题 11 时从代码的第 5 行收到此错误?

for x in matrix:
    p = 0
    for y in x:
        if p < 17:
            currentProduct = int(y) * int(x[p + 1]) * int(x[p + 2]) * int(x[p + 3])
            if currentProduct > highestProduct:
                print(currentProduct)
                highestProduct = currentProduct
        else:
                break
            p += 1
'generator' object is not subscriptable

Your x value is is a generator object, which is an Iterator : it generates values in order, as they are requested by a for loop or by calling next(x) .您的x值是一个生成器 object,它是一个Iterator :它按顺序生成值,因为它们是由for循环或调用next(x)请求的。

You are trying to access it as though it were a list or other Sequence type, which let you access arbitrary elements by index as x[p + 1] .您正在尝试访问它,就好像它是一个列表或其他Sequence类型一样,它允许您按索引访问任意元素x[p + 1]

If you want to look up values from your generator's output by index, you may want to convert it to a list:如果要按索引从生成器的 output 中查找值,您可能需要将其转换为列表:

x = list(x)

This solves your problem, and is suitable in most cases.这解决了您的问题,并且适用于大多数情况。 However, this requires generating and saving all of the values at once, so it can fail if you're dealing with an extremely long or infinite list of values, or the values are extremely large.但是,这需要一次生成和保存所有值,因此如果您要处理一个极长或无限的值列表,或者这些值非常大,它可能会失败。

If you just needed a single value from the generator, you could instead use itertools.islice(x, p) to discard the first p values, then next(...) to take the one you need.如果您只需要生成器中的单个值,则可以改为使用itertools.islice(x, p)丢弃第一个p值,然后使用next(...)获取您需要的值。 This eliminate the need to hold multiple items in memory or compute values beyond the one you're looking for.这消除了在 memory 中保存多个项目或计算超出您正在寻找的值的需要。

import itertools

result = next(itertools.islice(x, p))

As an extension to Jeremy's answer some thoughts about the design of your code:作为 Jeremy 的回答的扩展,关于代码设计的一些想法:

Looking at your algorithm, it appears that you do not actually need truly random access to the values produced by the generator: At any point in time you only need to keep four consecutive values (three, with an extra bit of optimization).查看您的算法,您似乎实际上并不需要真正随机访问生成器生成的值:在任何时间点,您只需要保留四个连续的值(三个,带有额外的优化)。 This is a bit obscured in your code because you mix indexing and iteration: If indexing would work (which it doesn't), your y could be written as x[p + 0] .这在您的代码中有点模糊,因为您混合了索引和迭代:如果索引可以工作(它不起作用),您的y可以写为x[p + 0]

For such algorithms, you can apply kind of a "sliding window" technique, demonstrated below in a stripped-down version of your code:对于此类算法,您可以应用一种“滑动窗口”技术,如下所示在您的代码的精简版本中:

import itertools, functools, operator
vs = [int(v) for v in itertools.islice(x, 3)]
for v in x:
    vs.append(int(v))
    currentProduct = functools.reduce(operator.mul, vs, 1)
    print(currentProduct)
    vs = vs[1:]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM