Python进阶——迭代器和可迭代对象有什么区别?

{"type":"doc","content":[{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"阅读本文大约需要 12 分钟。","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 Python 开发中,我们经常听到有关「容器」、「迭代器」、「可迭代对象」、「生成器」的概念。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们经常把这些概念搞混淆,它们之间有哪些联系和区别呢?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这篇文章,我们就来看一下它们之间的关系。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"容器","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先,我们先来看一下容器是如何定义的?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"简单来说,容器就是存储某些元素的统称,它最大的特性就是判断一个元素是否在这个容器内。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"怎么理解这句话?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"很简单,在 Python 中,我们通常使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"in","attrs":{}}],"attrs":{}},{"type":"text","text":" 或 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"not in","attrs":{}}],"attrs":{}},{"type":"text","text":" 来判断一个元素存在/不存在于一个容器内。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"例如下面这个例子:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"print('x' in 'xyz') # True\nprint('a' not in 'xyz') # True\nprint(1 in [1, 2, 3]) # True\nprint(2 not in (1, 2, 3)) # False\nprint('x' not in {'a', 'b', 'c'}) # True\nprint('a' in {'a': 1, 'b': 2}) # True","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在这个例子中,我们可以看到 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"str","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"list","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"tuple","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"set","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"dict","attrs":{}}],"attrs":{}},{"type":"text","text":" 都可以通过 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"in","attrs":{}}],"attrs":{}},{"type":"text","text":" 或 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"not in","attrs":{}}],"attrs":{}},{"type":"text","text":" 来判断一个元素是否在存在/不存在这个实例中,所以这些类型我们都可以称作「容器」。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那为什么这些「容器」可以使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"in","attrs":{}}],"attrs":{}},{"type":"text","text":" 或 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"not in","attrs":{}}],"attrs":{}},{"type":"text","text":" 来判断呢?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这是因为它们都实现了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__contains__","attrs":{}}],"attrs":{}},{"type":"text","text":" 方法。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果我们也想自定义一个容器,只需像下面这样,在类中定义 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__contains__","attrs":{}}],"attrs":{}},{"type":"text","text":" 方法就可以了:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"class A:\n\n def __init__(self):\n self.items = [1, 2]\n\n def __contains__(self, item):\n return item in self.items\n\na = A()\nprint(1 in a) # True\nprint(2 in a) # True\nprint(3 in a) # False","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在这个例子中,类 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"A","attrs":{}}],"attrs":{}},{"type":"text","text":" 定义了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__contains__","attrs":{}}],"attrs":{}},{"type":"text","text":" 方法,所以我们就可以使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"1 in a","attrs":{}}],"attrs":{}},{"type":"text","text":" 的方式去判断这个元素是否在 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"A","attrs":{}}],"attrs":{}},{"type":"text","text":" 这个容器内。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"换句话说,一个类只要实现了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__contains__","attrs":{}}],"attrs":{}},{"type":"text","text":" 方法,那么它就是一个「容器」。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们在开发时,除了使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"in","attrs":{}}],"attrs":{}},{"type":"text","text":" 判断元素是否在容器内之外,另外一个常用的功能是:输出容器内的所有元素。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"例如执行 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"for x in [1, 2, 3]","attrs":{}}],"attrs":{}},{"type":"text","text":",就可以迭代出容器内的所有元素。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那使用这种方式输出元素,是如何实现的?这就跟「迭代器」有关","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"迭代器","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一个对象要想使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"for","attrs":{}}],"attrs":{}},{"type":"text","text":" 的方式迭代出容器内的所有数据,这就需要这个类实现「迭代器协议」。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也就是说,一个类如果实现了「迭代器协议」,就可以称之为「迭代器」。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"什么是「迭代器协议」呢?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 Python 中,实现迭代器协议就是实现以下 2 个方法:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"__iter__","attrs":{}}],"attrs":{}},{"type":"text","text":":这个方法返回对象本身,即 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"self","attrs":{}}],"attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"__next__","attrs":{}}],"attrs":{}},{"type":"text","text":":这个方法每次返回迭代的值,在没有可迭代元素时,抛出 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"StopIteration","attrs":{}}],"attrs":{}},{"type":"text","text":" 异常","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下面我们来看一个实现迭代器协议的例子:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"# coding: utf8\n\nclass A:\n \"\"\"A 实现了迭代器协议 它的实例就是一个迭代器\"\"\"\n def __init__(self, n):\n self.idx = 0\n self.n = n\n\n def __iter__(self):\n print('__iter__')\n return self\n\n def __next__(self):\n if self.idx < self.n:\n val = self.idx\n self.idx += 1\n return val\n else:\n raise StopIteration()\n\n# 迭代元素\na = A(3)\nfor i in a:\n print(i)\n# 再次迭代 没有元素输出 因为迭代器只能迭代一次\nfor i in a:\n print(i)\n\n# __iter__\n# 0\n# 1\n# 2\n# __iter__","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在这个例子中,我们定义了一个类 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"A","attrs":{}}],"attrs":{}},{"type":"text","text":",它内部实现了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__iter__","attrs":{}}],"attrs":{}},{"type":"text","text":" 和 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"next","attrs":{}}],"attrs":{}},{"type":"text","text":" 方法。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其中 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__iter__","attrs":{}}],"attrs":{}},{"type":"text","text":" 方法返回了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"self","attrs":{}}],"attrs":{}},{"type":"text","text":",","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"next","attrs":{}}],"attrs":{}},{"type":"text","text":" 方法实现了具体的迭代细节。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然后执行 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"a = A(3)","attrs":{}}],"attrs":{}},{"type":"text","text":",在执行 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"for i in a","attrs":{}}],"attrs":{}},{"type":"text","text":" 时,我们看到调用了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__iter__","attrs":{}}],"attrs":{}},{"type":"text","text":" 方法,然后依次输出 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"next","attrs":{}}],"attrs":{}},{"type":"text","text":" 中的元素。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其实在执行 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"for","attrs":{}}],"attrs":{}},{"type":"text","text":" 循环时,实际执行流程是这样的:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"for i in a","attrs":{}}],"attrs":{}},{"type":"text","text":" 相当于执行 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"iter(a)","attrs":{}}],"attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"每次迭代时会执行一次 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__next__","attrs":{}}],"attrs":{}},{"type":"text","text":" 方法,返回一个值","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"如果没有可迭代的数据,抛出 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"StopIteration","attrs":{}}],"attrs":{}},{"type":"text","text":" 异常,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"for","attrs":{}}],"attrs":{}},{"type":"text","text":" 会停止迭代","attrs":{}}]}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是请注意,当我们迭代完 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"for i in a","attrs":{}}],"attrs":{}},{"type":"text","text":" 时,如果再次执行迭代,将不会有任何数据输出。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果我们想每次执行都能迭代元素,只需每次迭代一个新对象即可:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"# 每次都迭代一个对象\nfor i in A(3):\n print(i)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"可迭代对象","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"明白了「迭代器」是如何执行的,我们接着来看什么是「可迭代对象」?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这是什么意思?难道一个类是「迭代器」,那么它的实例不是一个「可迭代对象」吗? 它们之间又有什么区别?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其实,但凡是可以返回一个「迭代器」的对象,都可以称之为「可迭代对象」。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"换句话说:","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"__iter__","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" 方法返回一个迭代器,那么这个对象就是「可迭代对象」。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"听起来不太好理解,我们来看一个例子。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"class A:\n # A是迭代器 因为它实现了 __iter__ 和__next__方法\n def __init__(self, n):\n self.idx = 0\n self.n = n\n\n def __iter__(self):\n return self\n\n def __next__(self):\n if self.idx < self.n:\n val = self.idx\n self.idx += 1\n return val\n else:\n raise StopIteration()\n\nclass B:\n # B不是迭代器 但B的实例是一个可迭代对象\n # 因为它只实现了 __iter__\n # __iter__返回了A的实例 迭代细节交给了A\n def __init__(self, n):\n self.n = n\n\n def __iter__(self):\n return A(self.n)\n\n# a是一个迭代器 同时也是一个可迭代对象\na = A(3)\nfor i in a:\n print(i)\n# <__main__.a object="" at="">\nprint(iter(a))\n\n# b不是迭代器 但它是可迭代对象 因为它把迭代细节交给了A\nb = B(3)\nfor i in b:\n print(i)\n# <__main__.a object="" at="">\nprint(iter(b))","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"仔细看这个例子,我们定义了 2 个类 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"A","attrs":{}}],"attrs":{}},{"type":"text","text":" 和 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"B","attrs":{}}],"attrs":{}},{"type":"text","text":",","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"A","attrs":{}}],"attrs":{}},{"type":"text","text":" 实现了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"iter","attrs":{}}],"attrs":{}},{"type":"text","text":" 和 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"next","attrs":{}}],"attrs":{}},{"type":"text","text":" 方法。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"B","attrs":{}}],"attrs":{}},{"type":"text","text":" 只实现了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__iter__","attrs":{}}],"attrs":{}},{"type":"text","text":",并没有实现 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__next__","attrs":{}}],"attrs":{}},{"type":"text","text":",而且它的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"iter","attrs":{}}],"attrs":{}},{"type":"text","text":" 返回值是一个 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"A","attrs":{}}],"attrs":{}},{"type":"text","text":" 的实例。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对于 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"A","attrs":{}}],"attrs":{}},{"type":"text","text":" 来说:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"A","attrs":{}}],"attrs":{}},{"type":"text","text":" 是一个「迭代器」,因为其实现了迭代器协议 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__iter__","attrs":{}}],"attrs":{}},{"type":"text","text":" 和 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"next","attrs":{}}],"attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"同时 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"A","attrs":{}}],"attrs":{}},{"type":"text","text":" 的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__iter__","attrs":{}}],"attrs":{}},{"type":"text","text":" 方法返回了实例本身 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"self","attrs":{}}],"attrs":{}},{"type":"text","text":",也就是说返回了一个迭代器,所以 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"A","attrs":{}}],"attrs":{}},{"type":"text","text":" 的实例 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"a","attrs":{}}],"attrs":{}},{"type":"text","text":" 也是一个「可迭代对象」","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对于","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"B","attrs":{}}],"attrs":{}},{"type":"text","text":" 来说:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"B","attrs":{}}],"attrs":{}},{"type":"text","text":" 不是一个「迭代器」,因为它只了实现 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__iter__","attrs":{}}],"attrs":{}},{"type":"text","text":",没有实现 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"next","attrs":{}}],"attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由于 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"B","attrs":{}}],"attrs":{}},{"type":"text","text":" 的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__iter__","attrs":{}}],"attrs":{}},{"type":"text","text":" 返回了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"A","attrs":{}}],"attrs":{}},{"type":"text","text":" 的实例,而 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"A","attrs":{}}],"attrs":{}},{"type":"text","text":" 是一个迭代器,所以 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"B","attrs":{}}],"attrs":{}},{"type":"text","text":" 的实例 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"b","attrs":{}}],"attrs":{}},{"type":"text","text":" 是一个「可迭代对象」,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"换句话说,","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"B","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" 把迭代细节交给了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"A","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"总之,一个类的迭代细节,是可以交给另一个类的,就像这个例子的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"B","attrs":{}}],"attrs":{}},{"type":"text","text":" 这样,所以 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"B","attrs":{}}],"attrs":{}},{"type":"text","text":" 的实例只能是「可迭代对象」,而不是「迭代器」。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其实,这种情况我们见的非常多,我们使用最多的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"list","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"tuple","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"set","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"dict","attrs":{}}],"attrs":{}},{"type":"text","text":" 类型,都只是「可迭代对象」,但不是「迭代器」,因为它们都是把迭代细节交给了另外一个类,这个类才是真正的迭代器。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"看下面这个例子,你就能明白这两者之间的差别了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"# list 是可迭代对象\n>>> l = [1, 2]\n# list 的迭代器是 list_iterator\n>>> iter(l)\n\n# 执行的是 list_iterator 的 __next__\n>>> iter(l).__next__()\n>>> 1\n\n# tuple 是可迭代对象\n>>> t = ('a', 'b')\n# tuple 的迭代器是 tuple_iterator\n>>> iter(t)\n\n# 执行的是 tuple_iterator 的 __next__\n>>> iter(t).__next__()\n>>> a\n\n# set 是可迭代对象\n>>> s = {1, 2}\n# set 的迭代器是 set_iterator\n>>> iter(s)\n\n# 执行的是 set_iterator 的 __next__\n>>> iter(s).__next__()\n>>> 1\n\n# dict 是可迭代对象\n>>> d = {'a': 1, 'b': 2}\n# dict 的迭代器是 dict_keyiterator\n>>> iter(d)\n# 执行的是 dict_keyiterator 的 __next__\n\n>>> iter(d).next()\n>>> a","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"list","attrs":{}}],"attrs":{}},{"type":"text","text":" 类型为例,我们先定义 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"l = [1, 2]","attrs":{}}],"attrs":{}},{"type":"text","text":",然后执行 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"iter(l)","attrs":{}}],"attrs":{}},{"type":"text","text":" 得到 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"list","attrs":{}}],"attrs":{}},{"type":"text","text":" 类型的迭代器是 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"list_iterator","attrs":{}}],"attrs":{}},{"type":"text","text":",也就是说在迭代 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"list","attrs":{}}],"attrs":{}},{"type":"text","text":" 时,其实执行的是 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"list_iterator","attrs":{}}],"attrs":{}},{"type":"text","text":" 的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"next","attrs":{}}],"attrs":{}},{"type":"text","text":",","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"list","attrs":{}}],"attrs":{}},{"type":"text","text":" 把具体的迭代细节,交给了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"list_iterator","attrs":{}}],"attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"list","attrs":{}}],"attrs":{}},{"type":"text","text":" 是一个可迭代对象,但它不是迭代器。其他类型 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"tuple","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"set","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"dict","attrs":{}}],"attrs":{}},{"type":"text","text":" 也是同样的道理。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由此我们可以得出一个结论:","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"迭代器一定是个可迭代对象,但可迭代对象不一定是迭代器。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"生成器","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们再来看什么是「生成器」?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其实,「生成器」是一个特殊的「迭代器」,并且它也是一个「可迭代对象」。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有 2 种方式可以创建一个生成器:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"生成器表达式","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"生成器函数","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用生成器表达式创建一个生成器的例子如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"# 创建一个生成器 类型是 generator\n>>> g = (i for i in range(5))\n>>> g\n at 0x101334f50>\n# 生成器就是一个迭代器\n>>> iter(g)\n at 0x101334f50>\n# 生成器也是一个可迭代对象\n>>> for i in g:\n... print(i)\n# 0 1 2 3 4","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"注意看这个例子,我们使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"g = (i for i in range(5))","attrs":{}}],"attrs":{}},{"type":"text","text":" 创建了一个生成器,它的类型是 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"generator","attrs":{}}],"attrs":{}},{"type":"text","text":",同时调用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"iter(g)","attrs":{}}],"attrs":{}},{"type":"text","text":" 可以得知 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"iter","attrs":{}}],"attrs":{}},{"type":"text","text":" 返回的是实例本身,即生成器也是一个迭代器,并且它也是一个可迭代对象。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"再来看用函数创建一个生成器:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"def gen(n):\n for i in range(n):\n yield i\n\n# 创建一个生成器\ng = gen(5)\n# \nprint(g)\n# \nprint(type(g))\n\n# 迭代这个生成器\nfor i in g:\n print(i)\n# 0 1 2 3 4","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在这个例子中,我们在函数中使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"yield","attrs":{}}],"attrs":{}},{"type":"text","text":" 关键字。其实,包含 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"yield","attrs":{}}],"attrs":{}},{"type":"text","text":" 关键字的函数,不再是一个普通的函数,而返回的是一个生成器。它在功能上与上面的例子一样,可以迭代生成器中的所有数据。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通常情况下,我们习惯在函数内使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"yield","attrs":{}}],"attrs":{}},{"type":"text","text":" 的方式来创建一个生成器。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,使用生成器迭代数据相比于普通方式迭代数据,有什么优势呢?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这就要来看一下使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"yield","attrs":{}}],"attrs":{}},{"type":"text","text":" 的函数和使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"return","attrs":{}}],"attrs":{}},{"type":"text","text":" 的普通函数,有什么区别了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"yield","attrs":{}}],"attrs":{}},{"type":"text","text":" 的函数与使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"return","attrs":{}}],"attrs":{}},{"type":"text","text":" 的函数,在执行时的差别在于:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"包含 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"return","attrs":{}}],"attrs":{}},{"type":"text","text":" 的方法会以 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"return","attrs":{}}],"attrs":{}},{"type":"text","text":" 关键字为最终返回,每次执行都返回相同的结果","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"包含 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"yield","attrs":{}}],"attrs":{}},{"type":"text","text":" 的方法一般用于迭代,每次执行时遇到 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"yield","attrs":{}}],"attrs":{}},{"type":"text","text":" 就返回 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"yield","attrs":{}}],"attrs":{}},{"type":"text","text":" 后的结果,但内部会保留上次执行的状态,下次继续迭代时,会继续执行 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"yield","attrs":{}}],"attrs":{}},{"type":"text","text":" 之后的代码,直到再次遇到 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"yield","attrs":{}}],"attrs":{}},{"type":"text","text":" 后返回","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"当我们想得到一个集合时,如果使用普通方法,只能一次性创建出这个集合,然后 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"return","attrs":{}}],"attrs":{}},{"type":"text","text":" 返回:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"def gen_data(n):\n # 创建一个集合\n return [i for i in range(n)]","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但如果此时这个集合中的数据非常多,我们就需要在内存中一次性申请非常大的内存空间来存储。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果我们使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"yield","attrs":{}}],"attrs":{}},{"type":"text","text":" 生成器的方式迭代这个集合,就能解决内存占用大的问题:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"python"},"content":[{"type":"text","text":"for gen_data(n):\n for i in range(n):\n # 每次只返回一个元素\n yield i","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用生成器创建这个集合,只有在迭代执行到 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"yield","attrs":{}}],"attrs":{}},{"type":"text","text":" 时,才会返回一个元素,在这个过程中,不会一次性申请非常大的内存空间。当我们面对这种场景时,使用生成器就非常合适了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其实,生成器在 Python 中还有很大的用处,我会在后面的文章讲解 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"yield","attrs":{}}],"attrs":{}},{"type":"text","text":" 时,再进行详细的分析。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"总结","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"总结一下,这篇文章我们主要分析了 Python 中「容器」、「迭代器」、「可迭代对象」、「生成器」的联系和区别,用一张图表示它们的关系:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/48/486a637a99957e74aa6d47b093a5c509.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果一个类实现了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__iter__","attrs":{}}],"attrs":{}},{"type":"text","text":" 和 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"__next__","attrs":{}}],"attrs":{}},{"type":"text","text":" 方法,那么它就是一个迭代器。如果只是实现了 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"iter","attrs":{}}],"attrs":{}},{"type":"text","text":",并且这个方法返回的是一个迭代器类,那么这个类的实例就只是一个可迭代对象,因为它的迭代细节是交给了另一个类来处理。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"像我们经常使用的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"list","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"tuple","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"set","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"dict","attrs":{}}],"attrs":{}},{"type":"text","text":" 类型,它们并不是迭代器,只能叫做可迭代对象,它们的迭代细节都是交给了另一个类来处理的。由此我们也得知,一个迭代器一定是一个可迭代对象,但可迭代对象不一定是迭代器。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而生成器可以看做是一个特殊的迭代器,同时它也是一个可迭代对象。使用生成器配合 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"yield","attrs":{}}],"attrs":{}},{"type":"text","text":" 使用,我们可以实现懒惰计算的功能,同时,我们也可以用非常小的内存,来迭代一个大集合中的数据。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c1/c10b027be63b0c5c1ffc36a76a4a974b.png","alt":null,"title":"","style":[{"key":"width","value":"25%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"关注「水滴与银弹」公众号,7年资深后端研发,和你分享更多优质技术干货。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章