那是一个迭代器。您可以将其转换为 a list
ortuple
使用list(combinations('12345', 3))
or tuple(combinations('12345', 3))
。
根据您的问题,我认为您可能对什么是序列、可迭代对象和迭代器有些困惑。我认为完全理解它们以便能够编写和/或理解 python 代码是很有用的,所以我会试着给你一个关于这个问题的解释。
和list
对象tuple
是序列。序列是支持某些特定操作的对象。即它们是可迭代的(你可以这样做for elem in sequence
),它们支持“项目访问”(sequence[key]
有效)它们具有“长度”(len(sequence)
有效)并且您可以检查项目是否在序列中(elem in sequence
有效)。[有构成“序列协议”的操作的完整列表。唉,它是特定于 C-API 的。然而,这些函数的名称和解释应该让您了解它们支持的完整操作集]
在 python 中,还有另外两种对象在某些情况下可以用来代替序列:iterables和iterators。
可迭代对象是支持迭代的对象。说到python,如果一个对象有一个__iter__
返回迭代器的方法,它就是可迭代的。
迭代器是一个对象,它在一个可迭代对象上迭代一次并一个一个地产生值。在 python 中,迭代器是一个实现__iter__
and__next__
方法的对象(next
在 python2 中)。__iter__
通常“什么都不做”,只是返回对象本身。该next
方法返回迭代中的下一个值。
现在,combinations('12345', 3)
是一个可迭代对象,这意味着您可以遍历它,但您无法使用iterable[key]
语法访问它的项目,也无法使用len
.
为什么要使用迭代器?在某些情况下,您可以避免将整个值序列放入内存以对其进行迭代。例如,如果您想遍历数字1
,100
则不必创建一个充满数字list
的长度并对其进行迭代。100
给出一个可以计算下一个相加的值1
。
所以基本上可迭代是一种减少内存使用的方法,并且通常是“循环某些东西”所需的功能的抽象。如果你想要一个序列,你可以如前所述转换它们。
一种特殊的迭代器是所谓的生成器。生成器只是可以使用函数语法编写的迭代器,特别是它们使用yield
关键字:
>>> def numbers(n):
... while n > 0:
... yield n
... n -= 1
...
>>> numbers(5)
<generator object numbers at 0xb744a93c>
>>> for elem in numbers(5):
... print elem
...
5
4
3
2
1
如您所见,当您调用numbers
代码时未执行。相反,python 创建了一个生成器对象,它是一个迭代器。当您迭代对象时,函数内的代码将被执行,直到yield
遇到。发生这种情况时,返回“参数”yield
并冻结执行。当新的迭代开始时,它会重新开始。
或许你可以在这个例子中更好地看到执行流程:
>>> def flow():
... yield 'Execution stopped here'
... yield 'Execution continues'
... yield 'Execution ended'
...
>>> generator = flow()
>>> next(generator) #same as generator.__next__()
'Execution stopped here'
>>> next(generator)
'Execution continues'
>>> next(generator)
'Execution ended'
>>> next(generator)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
您可能有兴趣阅读提出它们的PEP255 。实际上它们已经被扩展以提供协程功能,但我认为这已经足够了。