在Python中“消费”是什么意思?在迭代器中?

时间:2011-03-03 22:32:24

标签: python iterator

我已经在Python工作了几个月了,而且我发现我经常忽略乍看之下逃避我的词汇,而不是试图获得一个想法的要点。现在,回头看,我仍然发现自己对消费所指的内容感到困惑。我最初的兴趣来自迭代器的解释,它说明了迭代器的消耗价值。但是,环顾四周,这在Python词典中似乎并不常见。或者是吗?在这里挖掘主要是找到对Web服务的引用,以及关于如何隐藏这个或那个函数结果的一两个讨论。

我想那时,把我的无知分解为几个基点:

  1. “消费”在不同的Pythonic环境中做不同的事情吗?
  2. 消费时数据会发生什么变化,例如iter()
  3. 当一个变量被赋给一个迭代器的结果 - 所谓的消耗的数据 - 是否它不再属于迭代器?
  4. 在对迭代器的单次调用中,您是否可以从迭代器对象中使用多个值?
  5. 我希望这有点道理。请注意,这不涉及任何特定需要;我只是混淆了理性的合理性。

    编辑:还有一件事......迭代值(当用next()调用时)会留在内存中吗?

6 个答案:

答案 0 :(得分:6)

术语“使用”是一个非正式术语,指的是迭代器在Python中的工作方式。 “迭代器”是一个单个对象,负责创建一些元素序列。此序列可能是现有列表的元素,也可能是计算的值,如素数或π的十进制数字。

当调用者从迭代器请求“next”项时,迭代器提供下一个项,然后更改其自己的状态,以便在此之后生成下一个项。这通常是你所期望的。

如果我有一个产生增加素数序列的发生器,我第一次调用它时会得到2作为回报。下一次,我会得到3.如果我然后给你一个对该生成器的引用,你将调用它(你认为是第一次)并获得5.没有任何方法可以“重置”除了通过创建一个全新的发生器实例之外,它将再次从2开始。在那种情况下,我可以说在给你生成器之前我已经消耗前两个项目了。

答案 1 :(得分:4)

我不是Python专家,但我可以这样说:大多数时候,编程中的消耗与生产相反。您可以将某些流程分类为生产者,从而创建价值;和其他人作为消费者,使用生产者创造的价值。

在迭代器的情况下,迭代器是一个生产者,它通过一个可迭代的对象并按顺序“生成”每个值,一次一个。从迭代器“消耗”数据只是意味着使用它。

答案 2 :(得分:4)

  

关于2。

事实上,我们必须区分两种情况。

记住Greg Hewgill所写的内容:

  

“迭代器”是一个负责的单个对象   用于创建一些元素序列。   此序列可能是现有列表的元素,   或者它可能是计算的东西,如素数   或π的小数位数。

第一种情况

迭代器计算受刺激时必须产生的对象;也就是说,在调用next()之前,生成的对象不存在。因此,如果为对象分配名称,后者将存活;如果没有,该对象将在某个时间内没有被绑定到命名空间中的名称而存在,然后它将在存储器中消失,也就是说它占据的位将在稍后或更早用于另一个对象。

第二种情况

是迭代器返回以前属于列表,元组,字典等的现有对象。在这种情况下,next()生成的每个对象都已经绑定了名称。然后,如果在从迭代器“弹出”对象时将对象分配给新名称,则会有两个绑定到对象的名称。如果对象未分配给名称,它将继续绑定到只有一个名称,足以维持对象的活动。

共同点:

每次通过调用迭代器生成对象时,如果没有为其分配名称,则操作的唯一结果是迭代器已被“消耗”。这是一种方式,即使在生成对象之后没有永久性后果,它也发生了一些让迭代器内部产生痕迹的东西。

人们谈到在为对象分配名称时使用迭代器,但是,我不想混淆。

注意:

事实上,如果某个对象预先存在于列表中,那么可能是它没有名称。但是列表中包含它“包含”的每个对象的引用......事实上,列表不是“包含”对象,而只是对对象的引用......这超出了我想说的范围。

  

关于3

你不应该写3:“当一个变量被分配给......时”

单词变量是Python中的一个陷阱,因为它有一个含糊不清的含义。在Python中没有变量,在其他语言中已知的常识中,也就是说«分隔的内存部分,其值可以改变»。只有对象。 变量一词通常用于表示标识符。因此,最好将其称为标识符名称。这避免了混淆。

  

关于4

我认为只用一次调用就可以从迭代器获得两次返回next()

答案 3 :(得分:1)

Iterators只是支持方法__iter__next的对象。迭代器的一般用例是遍历它们,每次循环时iterator.next()的结果都将分配给变量。

考虑到这一点,对iterator.next()的调用可以被称为“消耗一个值”,因为通常调用next会改变迭代器的状态,而且没有办法回到之前的状态。

但是,没有什么能阻止迭代器重复返回相同的值,甚至提供回滚到先前状态的方法。在那些使用“消费”一词的情况下可能不适用。

对于迭代器的next方法返回的数据所发生的情况,它完全依赖于迭代器的实现。生成器倾向于丢弃它们产生的结果,但如果容器也是迭代器,则在调用next()时返回的数据仍将存在于容器对象中。

答案 4 :(得分:0)

我可以回答你的第一点,消耗是耗尽一个迭代,这意味着运行下一个项目的迭代。

答案 5 :(得分:0)

  

"消费"在不同的Pythonic环境中做不同的事情?

不,"消费"总是做同样的事情。

  

消费时数据会发生什么变化,例如iter()?

从你得到的地方不再提供。

  

当一个变量被赋给一个迭代器的结果 - 所谓的消耗的数据 - 它是否不再属于迭代器?

正确。迭代器生成数据后,数据就不再属于迭代器。

  

在迭代器的单次调用中,您是否可以从迭代器对象中使用多个值?

通常,没有。但是,您可以编写一个自定义迭代器,一次生成多个值。