python - “TypeError:'生成器'对象不可下标”当我尝试使用 for 循环处理二维列表时
问题描述
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"
我正在尝试检查和更改仅包含对象的二维列表的项目。我首先构建了 2d 列表并尝试使用双 for 循环影响其中的项目,但它返回 TypeError。
Traceback (most recent call last):
File "test.py", line 12, in <module>
testList[m][n].name = "changed"
TypeError: 'generator' object is not subscriptable
我真的无法理解这里发生了什么,因为它看起来非常简单和可行。该脚本无法使用testList[0][0].name = "changed"
(而不是testList[m][n]
)运行,因此我怀疑不允许循环像这样运行。但为什么?
解决方案
当你输入时(foo for i in bar)
,你会得到一个生成器,当你输入时,[foo for i in bar]
你会得到一个列表。这两者之间的区别在于生成器在遍历时创建元素(生成),而列表将所有项目保存在内存中。这就是为什么(i for i in range(10))[2]
不可能,虽然[i for i in range(10)][2]
是。
当整个项目集太大而无法保存在内存中时,或者只是当您不需要同时将它们全部保存在内存中时,您应该使用生成器。例如,它们适用于在保持恒定内存使用的同时遍历文件。
现在,如果您想下标某些东西,例如foo[some_index]
thenfoo
需要是可下标的,而生成器不是,因为这样做会抛弃生成器存在的全部意义。虽然有人可能认为这(i for i in range(10))[2]
没问题,但扩展一些生成器可能最终会陷入无限循环,例如:
from itertools import count
even = (i for i in count() if i % 2 == 0)
这是完美的有效代码。count()
返回一个无限生成器。如果我们可以争论那even[1]
将是2
什么even[-1]
?没有最后一个偶数。因此,计算将永远进行。
反正。生成器在 python 中很常见,迟早您需要将其转换为列表或元组,您可以通过将它们传递给列表或元组构造函数list(range(10))
或tuple(range(10))
.
现在我认为我们有足够的背景来回答你的问题。您正在执行此操作testList = [(test("empty") for i in range(3)) for j in range(2)]
,这为我们提供了生成器列表。所以testList[m][n]
减少到事情发生(test("empty") for i in range(3))[n]
的地方。
如果你只是用括号替换括号,你就解决了你的问题,所以testList = [[test("empty") for i in range(3)] for j in range(2)]
.
推荐阅读
- c++ - 从 C++ 为字符串函数设置 _ENV
- kotlin - 在 Elvis 运算符中使用评估表达式是否最佳?
- php - PHP用数组中的值分配0值
- c - 一个函数,它包含两个 (pos) 整数 k 和 n 以及 1. 打印数字 1-.n 的所有长度为 k 的递增序列 2. 返回数字序列
- javascript - Try...catch 在 Google Apps 脚本中未按预期工作
- node.js - 如何成功响应从 Inventor 装配文件为 svf 文件创建的清单请求
- reactjs - eslint SyntaxError:无效的正则表达式标志
- ios - 如何知道我的应用何时聚焦或不聚焦——反应原生?
- python - SqlAlchemy 是否支持 SQL/JSON
- azure - Octopus Azure 部署在阵列参数上失败