Python &引用;类型错误:';发电机&x27;对象不可下标";当我试图用for循环处理二维列表时
我正在尝试检查和更改仅包含对象的二维列表的项。我首先构建了2d列表,并尝试使用double for循环影响其中的项目,但它返回TypeErrorPython &引用;类型错误:';发电机&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
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)