Python:在地图对象上调用“列表”两次

Posted

技术标签:

【中文标题】Python:在地图对象上调用“列表”两次【英文标题】:Python: calling 'list' on a map object twice 【发布时间】:2016-07-28 23:17:33 【问题描述】:

我想计算直到 n 的平方和。假设 n 为 4。然后此代码生成一个列表,其中包含 0 到 4 范围内的地图对象:

m = map(lambda x: x**2, range(0,4))

足够轻松。现在调用 m 上的 list,然后求和:

>>> sum(list(m))
14

出乎意料的行为是,如果我再次运行最后一行,总和为 0:

>>> sum(list(m))
0

我怀疑这是因为调用list(m) 返回一个空列表,但我找不到这种行为的解释。有人可以帮我解决这个问题吗?

【问题讨论】:

map 是一个 iterator,由第一个 list 调用使用。为什么不分配list(m) 并重复使用它? @jonrsharpe 是的,我看到这是另一种选择,但我想知道为什么会这样。所以你是说 list() 消耗迭代器?你能告诉我更多(或在哪里可以找到更多信息)吗? Python 教程/文档? Google 搜索 “python 迭代器”? 不,它不会:docs.python.org/3.0/whatsnew/… ...地图对象是一个迭代器 【参考方案1】:

map 在 Python 3 中返回一个有状态的迭代器。有状态的迭代器可能只被使用一次,之后它就被耗尽并且不产生任何值。

在您的代码 sn-p 中,您多次使用迭代器。 list(m) 每次尝试重新创建列表,并且对于第二次和下一次运行,创建的列表将始终为空(因为在第一次 list(m) 操作中消耗了源迭代器)。

只需将迭代器转换为列表一次,然后对所述列表进行操作。

m = map(lambda x: x**2, range(0,4))
l = list(m)
assert sum(l) == 14
assert sum(l) == 14

【讨论】:

如果您想避免生成器的这种行为,您可以跳过地图并使用列表推导直接进入列表。 m = [x**2 for x in range(4)] 我改变了你的答案,因为map() 返回的是迭代器,而不是生成器 - isinstance(map(lambda x: x**2, range(0,4)), types.GeneratorType) == False。返回的对象缺少send()throw(),由于map() 语义,这是合乎逻辑的,因为无法与正在映射的对象进行通信。

以上是关于Python:在地图对象上调用“列表”两次的主要内容,如果未能解决你的问题,请参考以下文章

Python:不能在类中使用函数两次,TypeError:'list'对象不可调用,为什么? [关闭]

在 viewDidLayoutSubviews() 中调用地图视图函数时,地图视图显示两次?

AngularJS:从下拉列表中选择任何选项时,函数在 ng-change 上触发两次

在地图项目上单击两次时,片段中的地图会在滑动抽屉中崩溃

意外的双重函数调用[重复]

如何在同一个“调用堆栈”中两次使用宏列表?