filter()ing a dict

Robin Cull robin.cull at pace.co.uk
Thu Aug 7 09:59:37 EDT 2003


Imagine I have a dict looking something like this:  

myDict = {"key 1": ["value 1", "value 2", "value 3", "value 4"], "key
2": ["value 1", "value 2"], "key 3": ["value2", "value 3", "value 4"],
"key 4": ["value 1", "value 2", "value 3", "value 4"]}

That is, a set of keys which have a variable length list of associated
values after them.  What I want to do is filter out a subset of this
dict to produce another dict that satisfies a set of criteria (in this
case whether it contains all four values) to end up with something
like this:

{"key 1": ["value 1", "value 2", "value 3", "value 4"], "key 4":
["value 1", "value 2", "value 3", "value 4"]}

I've tried using the filter() function so I wrote a small function
that returned True or False depending on whether the length of the
list was what I wanted e.g.

def f(item):
    if len(item) == 4:
        return True
    else:
        return False

I then called filter(f, myDict).  

I was expecting to be returned a dict which was the subset of myDict
that satisfied f.

This did not happen; the item passed to f was each key of the dict,
not each value list.  The call to filter returned an empty list (as
obviously none of the keys satisfied the criteria).  If anything I
would have expected an empty dict back as according to the docs:

    ""filter(function, sequence)" returns a sequence (of the same
type, if possible) consisting of those items from the sequence for
which function(item) is true."

The important bit here is "of the same type, if possible" which I
understood to mean if passed a dict it would return a dict.

I've tried calling filter(f, myDict.values()) which works and I get a
list like this returned:

[["value 1", "value 2", "value 3", "value 4"], ["value 1", "value 2",
"value 3", "value 4"]]

Sort of what I want but I've lost the associativity with the key which
was kind of the point in using a dict in the first place.

I'm guessing that filter() does not work on a dict in the way I think
it should.

I can write something to get around the behaviour in this particular
case (although suggestions would be welcome).

My question is, does anybody else think that when calling filter(f,
dict), it should return a dict of the keys and values of the former
dict where the values satisfy the conditions defined by f()?

Are there reasons for it not to work this way?  I must admit I've not
looked into this carefully, just in the context of my script it'd be
useful to.

What are the side effects of making filter() work this way?  

Thanks all.  

Regards, 

Robin




More information about the Python-list mailing list