"'生成器'对象不可订阅"错误

Mat*_*nah 33 python generator

在尝试解决Project Euler Problem 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
Run Code Online (Sandbox Code Playgroud)
'generator' object is not subscriptable
Run Code Online (Sandbox Code Playgroud)

小智 46

您的x值是一个生成器对象,它是Iterator:它按顺序生成值,因为它们是for循环请求或通过调用next(x).

您试图访问它,就像它是一个列表或其他Sequence类型,它允许您通过索引访问任意元素x[p + 1].

如果要按索引从生成器的输出中查找值,可能需要将其转换为列表:

x = list(x)
Run Code Online (Sandbox Code Playgroud)

这解决了您的问题,并且在大多数情况下都适用.但是,这需要一次生成并保存所有值,因此如果您处理极长或无限的值列表,或者值非常大,则可能会失败.

如果您只需要生成器中的单个值,则可以使用itertools.islice(x, p)丢弃第一个p值,然后使用所需的值next(...).这消除了在内存中保存多个项目或计算超出您正在寻找的值的需要的需要.

import itertools

result = next(itertools.islice(x, p))
Run Code Online (Sandbox Code Playgroud)

  • Python的"列表"*更接近数组而不是大多数其他语言称之为列表.它们会自动调整数组大小(许多语言称之为"向量",甚至只是"数组").它们不是链表,它们支持任何元素的常量类型查找,而不仅仅是头部,而不像大多数语言中的"列表". (6认同)
  • 应该提到的是,将生成器转换为列表与生成器的初始用例(例如,节省内存)相矛盾,这可能会使这种解决方案变得无用。 (2认同)