Python:调用方法返回< [object] at [pointer]>而不是对象

时间:2012-11-14 20:29:41

标签: python import module python-2.x

我是一个非常新手的程序员。我正在尝试使用combinations模块中的itertools工具。所以我试试:

from itertools import *
print combinations('12345', 3)

但不是预期的('123', '124', '125', [...]),而是<itertools.combinations object at [pointer]>。我很困惑,因为在其他模块中调用方法会返回预期的结果,例如:

import random
print random.randrange(10)
>>> 9

我对itertools模块做错了什么?

4 个答案:

答案 0 :(得分:6)

无。结果就是它应该是什么。您显然没有考虑的是结果是迭代器,而不是完全评估的结果列表/元组。您看到的输出是该对象的repr()(它是>返回一个字符串)。您可以通过将前者传递给list构造函数来将前者转换为后者:

import itertools
print list(itertools.combinations('12345', 3))

但是当你不需要它而你只是遍历值时,它会通过不同时存储所有结果来节省大量内存。它还允许通过不消耗整个迭代器来避免工作(例如,找到满足某些条件然后返回的第一个组合)。

答案 1 :(得分:3)

itertools.combinations返回一个iterable(您可以在Python文档中的equivalent codes中看到yield关键字的使用)。如果要打印完整序列,可以使用list(combinations(...))

>>> print list(combinations('12345', 3))
[('1', '2', '3'), ('1', '2', '4'), ('1', '2', '5'), ('1', '3', '4'), ('1', '3', '5' ('2', '3', '5'), ('2', '4', '5'), ('3', '4', '5')]

答案 2 :(得分:2)

这是一个迭代器。您可以使用listtuple将其转换为list(combinations('12345', 3))tuple(combinations('12345', 3))

根据你的问题我认为你可能会对序列,迭代和迭代器有什么困惑。我认为完全理解它们以便能够编写和/或理解python代码是有用的,所以我会尝试给你一个关于这个问题的解释。

listtuple个对象是序列。序列是支持某些特定操作的对象。即他们是 iterables (你可以做for elem in sequence),他们支持“项目访问”(sequence[key]有效)他们有“长度”(len(sequence)是有效),您可以检查项目是否在序列中(elem in sequence有效)。 [有complete list个操作构成“序列协议”。唉它特定于C-API。然而,这些函数的名称和解释应该让您了解它们支持的整套操作]

在python中还有另外两种对象,在某些情况下可以使用而不是序列: iterables iterators

iterable是一个支持迭代的对象。说到python,如果对象具有返回迭代器的__iter__方法,则该对象是可迭代的。

迭代器是一个在一个iterable上迭代一次并逐个产生值的对象。在python中,迭代器是一个实现__iter____next__方法(python2中的next)的对象。 __iter__ 通常“什么都不做”,只返回对象本身。 next方法返回iterable中的下一个值。

现在,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。实际上它们已被扩展为提供协程功能,但我认为现在已经足够了。

答案 3 :(得分:0)

itertools.combination是一个班级;因此,调用itertools.combinations()返回该实例的实例,该实例可以迭代以获取值:

for combo in combinations('12345', 3):
    print combo