Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python &引用;类型错误:';发电机&x27;对象不可下标";当我试图用for循环处理二维列表时_Python_For Loop_Iterator_Generator - Fatal编程技术网

Python &引用;类型错误:';发电机&x27;对象不可下标";当我试图用for循环处理二维列表时

Python &引用;类型错误:';发电机&x27;对象不可下标";当我试图用for循环处理二维列表时,python,for-loop,iterator,generator,Python,For Loop,Iterator,Generator,我正在尝试检查和更改仅包含对象的二维列表的项。我首先构建了2d列表,并尝试使用double for循环影响其中的项目,但它返回TypeError class test(object): def __init__(self, name): self.name = '' testList = [(test("empty") for i in range(3)) for j in range(2)] for m in range(3): for n in ran

我正在尝试检查和更改仅包含对象的二维列表的项。我首先构建了2d列表,并尝试使用double for循环影响其中的项目,但它返回TypeError

class test(object):
    def __init__(self, name):
        self.name = ''


testList = [(test("empty") for i in range(3)) for j in range(2)]


for m in range(3):
    for n in range(2):

        testList[m][n].name = "changed"
回溯(最近一次呼叫最后一次):
文件“test.py”,第12行,在
测试列表[m][n].name=“已更改”
TypeError:“生成器”对象不可下标

我真的无法理解这里发生了什么,因为它看起来非常简单和可行。脚本无法与
testList[0][0]一起运行。name=“changed”
(而不是
testList[m][n]
),因此我怀疑循环不允许这样运行。但是为什么呢?

您没有创建列表列表,而是创建了生成器对象列表。这些生成器对象处于休眠状态,直到代码对它们进行迭代,它们才处于活动状态。即使这样,您也没有索引,这是使用索引所必需的。为了能够分配给索引,您需要一个可变序列

如果要使每个嵌套索引可变,必须生成列表,而不是生成器。将
(…)
括号替换为
[…]
方括号以创建列表:

Traceback (most recent call last):
  File "test.py", line 12, in <module>
    testList[m][n].name = "changed"
TypeError: 'generator' object is not subscriptable
列表理解会立即执行,然后生成一个列表对象。列表是可变序列。

当您键入
(foo代表条形图中的i)
时,您将获得一个生成器,当您键入
[foo代表条形图中的i]
时,您将获得一个列表。这两者之间的区别在于生成器在遍历时创建元素(generate),而列表保存内存中的所有项。这就是为什么
(i代表范围(10)中的i))[2]
是不可能的,而
[i代表范围(10)][2]
是不可能的

当整组项太大而无法保存在内存中时,或者当不需要同时将它们全部保存在内存中时,应该使用生成器。例如,它们很适合遍历文件,同时保持恒定的内存使用率

现在,如果你想下标一些东西,比如
foo[some_index]
,那么
foo
需要是可下标的,而生成器不是,因为这样做会丢掉生成器存在的全部意义。虽然有人可能会认为
(范围(10)中的i代表i)[2]
没有问题,但扩展某些生成器可能会以无限循环结束,例如:

testList = [[test("empty") for i in range(3)] for j in range(2)]
这是完美有效的代码。
count()
返回一个无限生成器。如果我们可以说
偶数[1]
将是
2
那么
偶数[-1]
将是什么?没有最后的偶数。因此,计算将花费永远的时间

无论如何。生成器在python中很常见,您迟早需要将其转换为列表或元组,您可以通过将它们传递给列表或元组构造函数
list(range(10))
tuple(range(10))

现在我认为我们有足够的背景来回答你的问题。您正在对范围(3)中的i执行此
testList=[(测试(“空”)测试范围(2)中的j)]
这为我们提供了一个生成器列表。所以
testList[m][n]
减少到类似于
(test(“empty”)的范围(3)中的i)[n]
,这就是事情爆发的地方


如果用括号替换括号,就解决了问题,因此
testList=[[test(“empty”)表示范围(3)中的i]表示范围(2)]

如果需要嵌套列表,则两个级别都需要
[]
。目前,您有一个生成器列表,而不是列表列表。
from itertools import count
even = (i for i in count() if i % 2 == 0)