【问题标题】:What is the difference between list and iterator in Python? [closed]Python中的列表和迭代器有什么区别? [关闭]
【发布时间】:2014-10-28 12:36:27
【问题描述】:

我正在阅读《Think Python: How to think like a computer scientist》一书,它说在 Python 3.x 中,dict([list of tuples]) 返回一个 iterator 而不是 list(就像 Python 2.7 中的情况一样)。

这本书没有进一步解释,这让我很困惑。我特别想知道:

  1. 迭代器和列表有何不同,以及

  2. 返回迭代器优于列表有什么好处?

【问题讨论】:

  • 呃...dict(...) 返回一个dict。在两个 python 版本中。你指的是map吗?

标签: python python-3.x python-2.7 list iterator


【解决方案1】:

迭代器是一种机制,您可以通过它使用for 对列表或其他一些对象/值集进行迭代。列表实现了一个迭代器。但你也可以实现返回数字序列、随机字符串等的迭代器。

当你返回一个迭代器时,你只是返回了迭代对象;接收代码对底层容器或生成器算法一无所知。

迭代器是惰性的;他们只在被要求时返回序列或列表中的下一个元素。因此,您可以使用它们实现无限序列。

进一步阅读
Iterator Types
The for statement

【讨论】:

    【解决方案2】:

    迭代器是一个产生值的对象,但不一定与包含所有要产生的值的内存数据结构相关联。相比之下,列表是完全构造的并驻留在内存中。基本上,迭代器通常比作为内存结构创建的相同数据具有更高的内存效率,并且通常具有更高的性能,因为所有每个元素的计算都可以在访问元素而不是预先加载时完成,并且所有元素都不会'不需要驻留在内存中。

    【讨论】:

    • 那么 iter() 会返回一个生成器吗?
    【解决方案3】:

    这里的关键定义是:

    • List :完全存储在内存中,它也将是一个迭代器 - 即您可以从一个元素转到下一个元素。
    • Iterable :任何实现迭代器协议的对象 - 即允许您从一个元素转到下一个元素。它可以使用存储在内存中的数据,可以是一个文件,或者可以计算每个步骤。

    很多东西不是列表的可迭代对象,所有列表都是可迭代对象

    【讨论】:

      【解决方案4】:

      首先,你的书是错的(或者你误解了它):

      >>> dict([(1, 2), (3, 4), (5, 6)])
      {1: 2, 3: 4, 5: 6}
      

      如您所见,dict([list of tuples]) 在 Python 2.x 和 3.x 中都返回一个字典。

      列表和迭代器之间的根本区别在于列表包含许多按特定顺序排列的对象 - 例如,您可以从中间的某处拉出其中一个:

      >>> my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
      >>> my_list
      ['a', 'b', 'c', 'd', 'e', 'f', 'g']
      >>> my_list[3]
      'd'
      

      ...而迭代器产生以特定顺序的多个对象,通常根据要求动态创建它们:

      >>> my_iter = iter(range(1000000000000))
      >>> my_iter
      <range_iterator object at 0x7fa291c22600>
      >>> next(my_iter)
      0
      >>> next(my_iter)
      1
      >>> next(my_iter)
      2
      

      我在这里使用next() 进行演示;在实际代码中,使用 for 循环遍历迭代器更为常见:

      for x in my_iter:
          # do something with x
      

      注意权衡:一万亿个整数的列表将使用比大多数机器可用的内存更多的内存,这使得迭代器更加高效......但代价是无法在中间:

      >>> my_iter[37104]
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      TypeError: 'range_iterator' object is not subscriptable
      

      【讨论】:

      • 我是 Python 新手。如何调用任务生成的对象:“range()”?引用“range()”的正确方法是“任务”吗?
      • 非常翔实的答案,正是我想要的,谢谢。
      【解决方案5】:

      您应该在此处阅读 Python 文档的迭代器协议指南:https://docs.python.org/2/library/stdtypes.html#iterator-types

      基本上,Python 中的迭代器是符合通用 protocol 的迭代器,用于迭代容器中的元素。 list 是符合该协议的特定容器类型。

      【讨论】:

        【解决方案6】:

        列表是保存一系列值的数据结构。迭代器是一个对象,它提供一个接口,通过next 函数一次检索一个值。

        可迭代对象是提供__iter__ 方法的对象,当您将可迭代对象传递给iter 函数时会调用该方法。您通常不需要明确地执行此操作;例如,for 循环会隐式执行。像这样的循环

        for x in [1,2,3]:
            print x
        

        自动调用list__iter__ 方法。你可以明确地这样做

        for x in iter([1,2,3]):
            print x
        

        甚至更明确地使用

        for x in [1,2,3].__iter__():
            print x
        

        查看差异的一种方法是从一个单个列表创建两个迭代器。

        l = [1, 2, 3, 4, 5]
        i1 = iter(l)
        i2 = iter(l)
        print next(i1)   # 1
        print next(i1)   # 2
        print next(i2)   # 1 again; i2 is separate from i1
        print l          # [1, 2, 3, 4, 5]; l is unaffected by i1 or i2
        

        【讨论】:

        • 那么 iter() 返回一个生成器吗?因为它支持类似于生成器中的 yield 的 next()。
        • iter 返回一个迭代器。生成器只是一种迭代器。查看type(iter([1,2,3]))
        • 我认为任何允许 next() 方法的东西在内部都有一个作为生成器的产量
        • 这不正确。任何提供__next__(因此可以传递给next)的东西都是迭代器。可迭代是提供__iter__ 的东西(因此可以传递给iter)。生成器只是一种迭代器,由使用yield 的可调用对象创建,但并非所有迭代器都是使用yield 创建的。
        猜你喜欢
        • 2018-01-28
        • 1970-01-01
        • 2016-09-19
        • 2016-07-14
        • 2022-12-28
        • 1970-01-01
        • 2010-10-27
        • 2010-11-04
        • 1970-01-01
        相关资源
        最近更新 更多