Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
294 views
in Technique[技术] by (71.8m points)

python - How to filter a nested dictionary (pythonic way) for a specific value using map or filter instead of list comprehensions?

I've a nested dictionary.

>>> foo = {'m': {'a': 10}, 'n': {'a': 20}}
>>> 

I'd like to filter specific values, based on the values of 'a'.

I can use list comprehensions for the purpose.

>>> [foo[n] for n in foo if foo[n]['a'] == 10]
[{'a': 10}]
>>> 

Using list alone gives me the elements from foo (and not the values of the elements) - as expected:

>>> list(filter(lambda x: foo[x] if foo[x]['a']==10 else None,foo))
['m']
>>> 

Using map returns me unwanted 'None' values:

>>> list(map(lambda x: foo[x] if foo[x]['a']==10 else None,foo))
[{'a': 10}, None]
>>> 

Combining these two, I can fetch the desired value. But I guess foo is iterated twice - once each for filter and map. The list comprehension solution needs me to iterate just once.

>>> list(map(lambda t: foo[t], filter(lambda x: foo[x] if foo[x]['a']==10 else None,foo)))
[{'a': 10}]
>>> 

Here's another approach using just filter. This gives me the desired values but I'm not sure if iterating over values of a dictionary is a good/pythonic approach:

>>> list(filter(lambda x: x if x['a'] == 10 else None, foo.values()))
[{'a': 10}]
>>> 

I'd like to know if:

  1. What's the pythonic/recommended approach for this scenario?
  2. If the last example using filter on dictionary values is an acceptable?

Regards

Sharad

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A list comprehension can do this beautifully.

>>> foo = {'m': {'a': 10}, 'n': {'a': 20}}
>>> [v for v in foo.values() if 10 in v.values()]
[{'a': 10}]

You don't need the for loop or the list comprehension if you are matching against a known key in the dictionary.

In [15]: if 10 in foo['m'].values():
    ...:     result = [foo['m']]
    ...:     

In [16]: result
Out[16]: [{'a': 10}]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...