129

I am learning the concept of filters in Python. I am running a simple code like this.

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

But instead of getting a list, I am getting some message like this.

<filter object at 0x00FDC550>

What does this mean? Does it means that my filtered object i.e list to come out is stored at that memory location? How do I get the list which I need?

Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
Prasad
  • 5,946
  • 3
  • 30
  • 36

2 Answers2

212

It looks like you're using python 3.x. In python3, filter, map, zip, etc return an object which is iterable, but not a list. In other words,

filter(func,data) #python 2.x

is equivalent to:

list(filter(func,data)) #python 3.x

I think it was changed because you (often) want to do the filtering in a lazy sense -- You don't need to consume all of the memory to create a list up front, as long as the iterator returns the same thing a list would during iteration.

If you're familiar with list comprehensions and generator expressions, the above filter is now (almost) equivalent to the following in python3.x:

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

As opposed to:

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

in python 2.x

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • 1
    Thanks a lot. Also, please can you tell me what is this number 0x00FDC550 – Prasad Sep 07 '12 at 13:33
  • 8
    That's the object's ID. In CPython, it's the memory location. – mgilson Sep 07 '12 at 13:35
  • 2
    wow ... interesting ... I thought [] snd list() are equivalent, but [filter(func, data)] doesn't work the same – user2846569 Sep 18 '14 at 13:39
  • @user2846569: what's the difference ? – Mr_and_Mrs_D Nov 14 '14 at 10:07
  • 2
    @Mr_and_Mrs_D try putting an iterator object itObj in [] and you will get [itObj], while putting in list() you will get values from object like [1, 4, 7], assuming itObj has these values. – user2846569 Nov 14 '14 at 18:11
  • If I want to get the size of result, should convert to list, then call `len()`. Not so convenient as before. – Bin Nov 04 '16 at 15:44
  • 1
    @Bin -- Nope. It's a trade-off. The 3.x version is more efficient in many contexts (e.g. passing to `any` allows short circuiting). I think that picking up that efficiency as well as the ability to work with generators of arbitrary size were seen as sufficient benefits to give up the easy length checking. After all, to recover the ability to get the length, you just need to call `len(list(filter(...)))` instead of `len(filter(...))`. – mgilson Nov 04 '16 at 16:06
25

It's an iterator returned by the filter function.

If you want a list, just do

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

Nonetheless, you can just iterate over this object with a for loop.

for e in filter(f, range(2, 25)):
    do_stuff(e)
sloth
  • 99,095
  • 21
  • 171
  • 219
  • Thanks a lot. Also, please can you tell me what is this number 0x00FDC550 – Prasad Sep 07 '12 at 13:32
  • It's the memory address of that object. It's the default output when printing an object if the class of that object don't has the[`__repr__()`](http://docs.python.org/library/functions.html#repr) method that is used to control the output. – sloth Sep 07 '12 at 13:35