Filter function not working as expected

Hi there! :slight_smile:
So I’ve been trying to figure out why filt_val is not working the way expected.

animals = {"eagle": "bird", "monkey": "mammal", "koi": "fish", "lizard": "reptile"} filt_key = list(filter(lambda word: word if "a" in word else None, animals)) filt_val = list(filter(lambda word: animals[word] if word in filt_key else None, animals)) print(filt_key) print(filt_val) # This should print "['bird', 'reptile']" --> WHY NOT?? filt_dict = dict(zip(filt_key, filt_val)) print(filt_dict, end="\n\n") print("The above is the problem, down there ugly solution", "\n") # This does the same as filt_val except it cannot iterate through the dict of animals. filt_lambda = lambda word: animals[word] if word in filt_key else None print(filt_lambda("eagle")) # prints "bird" as expected # For some reason though if written in such an ugly manner like the following, it works. filt_val2_list = [] filt_val2 = list(filter(lambda word: filt_val2_list.append(animals[word]) if word in filt_key else None, animals)) print(filt_val2_list) print(dict(zip(filt_key, filt_val2_list))) # Voila, works... but it makes no sense to me why the first one does not. Essentially it does literally the same thing, except for that filt_val2 appends the result onto a different list which is really just a waste of time and code.

So I have been trying to find an explanation for that for around 2-3 hours now. There is literally nothing on the internet about iteration with filter function through dictionaries. If you try to find it all the people write “iteration through dictionaries with filter function” and then they proceed to iterate through a LIST of dictionaries. Like, God, that’s not iterating through dictionaries at all, it is just the same as with an ordinary list.
Hence, as I had tried to solve it myself for some time now I do not wish to suffer more with it and I came here in hopes of someone being able to explain it to me.
Thank you in advance! I mean there must be someone who can tell me why the ugly one works and the expected one not :sweat_smile:

I may be wrong, but what I believe is happening is filter is creating its new list using what it’s iterating through. Which in the case of a dictionary will be the keys - so the new list will be based on them.
There may be a way to extract what you want using filter, other than what you’ve done, but there are also other methods to get the same results;
list comprehension

filt_val = [val for (key,val) in animals.items() if key in filt_key]

would give you [‘bird’, ‘reptile’] as you expected.

however, you could also use dictionary comprehension

new_dict = {key:val for (key,val) in animals.items() if "a" in key}

which will get you to the end result in one fell swoop.

Hope that helps.

1 Like

Hi there, pluginmaybe haha we meet again :slight_smile:
I was suspecting something similar like you that filter function creates a new list of which it uses to iterate through data. But then I noticed if I replace the animals[word] with anything that is not a function it is not going to give me an error, rather it is going to just do the same thing as before, which shouldn’t happen if it uses a list and tries to find a value that is not there. Or maybe it has a default assigned having asked for something not in the list is going to result in the default value which is the filter’s own list’s values. Kind of sad though because it could simply work with dictionaries too.
I also thought of using simple loops instead but that’d be more code, so I wanted to keep it clean and I really like the idea of using comprehensions as you showed, I didn’t really think of that.
Thanks for your help, we shall meet again haha, Take care

1 Like