调用 filter 返回 <filter object at ...>。

129

我正在学习Python中的过滤器概念。我运行了一个类似于这样的简单代码。

>>> def f(x): return x % 2 != 0 and x % 3 != 0
>>> filter(f, range(2, 25))

但是我没有得到一个列表,而是收到了这样的一条消息。

<filter object at 0x00FDC550>
这是什么意思?这是否意味着我的筛选对象即列表存储在那个内存位置?我如何获取我需要的列表?
2个回答

213

看起来您正在使用Python 3.x。在Python 3中,filtermapzip等函数返回的是可迭代对象,而不是列表。换句话说,

filter(func,data) #python 2.x

等同于:

list(filter(func,data)) #python 3.x
我认为这是因为通常你想以懒惰的方式进行过滤 - 你不需要消耗所有的内存来预先创建一个列表,只要迭代器在迭代期间返回与列表相同的内容即可。如果你熟悉列表推导式和生成器表达式,那么上面的过滤器现在(几乎)等价于Python3.x中的以下内容:
( x for x in data if func(x) ) 

与之相反:

[ x for x in data if func(x) ]

在 Python 2.x 中


1
非常感谢。另外,请问这个数字0x00FDC550是什么意思? - Prasad
8
那是对象的ID。在CPython中,它是内存位置。 - mgilson
2
哇...有趣...我以为[]和list()是等价的,但[filter(func, data)]的效果不同。 - user2846569
2
@Mr_and_Mrs_D 试着将一个迭代器对象 itObj 放进 [] 中,你会得到 [itObj],如果放进 list() 中,假设 itObj 包含了 [1, 4, 7] 这些值,你会得到类似 [1, 4, 7] 的数值列表。 - user2846569
1
@Bin -- 不是的。这是一个权衡。在许多情况下,3.x版本更有效率(例如,传递给“any”允许短路)。我认为,获得这种效率以及能够处理任意大小的生成器被视为足够的好处,放弃了简单的长度检查。毕竟,要恢复获取长度的能力,您只需要调用len(list(filter(...)))而不是len(filter(...)) - mgilson
显示剩余3条评论

25

这是由filter函数返回的iterator

如果你想要一个列表,只需要执行

list(filter(f, range(2, 25)))

然而,您可以使用for循环迭代此对象。

for e in filter(f, range(2, 25)):
    do_stuff(e)

非常感谢。另外,请问这个数字0x00FDC550是什么意思? - Prasad
这是该对象的内存地址。如果该对象的类没有__repr __()方法来控制输出,则在打印对象时会使用默认输出。 - sloth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接