如何使用映射或过滤器而不是列表推导来过滤特定值的嵌套字典(pythonic 方式)?

Sha*_*rad 7 python dictionary list-comprehension list python-3.5

我有一个嵌套字典。

>>> foo = {'m': {'a': 10}, 'n': {'a': 20}}
>>> 
Run Code Online (Sandbox Code Playgroud)

我想根据“a”的值过滤特定值。

为此,我可以使用列表推导式。

>>> [foo[n] for n in foo if foo[n]['a'] == 10]
[{'a': 10}]
>>> 
Run Code Online (Sandbox Code Playgroud)

单独使用 list 会给我来自 foo 的元素(而不是元素的值) - 正如预期的那样:

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

使用地图返回我不需要的“无”值:

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

结合这两者,我可以获取所需的值。但我猜 foo 被迭代了两次 - 一次用于过滤器和映射。列表理解解决方案只需要我迭代一次。

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

这是另一种仅使用过滤器的方法。这给了我想要的值,但我不确定迭代字典的值是否是一个好的/pythonic 方法:

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

我想知道是否:

  1. 这个场景的pythonic/推荐方法是什么?
  2. 如果最后一个对字典值使用过滤器的例子是可以接受的?

问候

沙拉德

sty*_*ane 6

列表理解可以很好地做到这一点。

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

如果您与字典中的已知键匹配,则不需要 for 循环或列表理解。

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

In [16]: result
Out[16]: [{'a': 10}]
Run Code Online (Sandbox Code Playgroud)


Kar*_*rin 5

如果您想返回包含 的完整嵌套字典a,列表理解可能是最干净的方法。您的初始列表理解将起作用:

[foo[n] for n in foo if foo[n]['a'] == 10]
Run Code Online (Sandbox Code Playgroud)

您还可以通过以下方式避免查找n

[d for d in foo.values() if d['a'] == 10]
Run Code Online (Sandbox Code Playgroud)

列表推导式通常被认为比此类更简单的问题mapfilter相关方法更 Pythonic ,但如果您使用预定义的函数mapfilter当然也有其一席之地。

这给了我所需的值,但我不确定迭代字典的值是否是一种好的/pythonic 方法。

如果您想返回满足特定条件的字典的所有值,我不确定您将如何绕过迭代字典的值。

对于基于过滤器的方法,我会这样做:

list(filter(lambda x: x['a'] == 10, foo.values()))
Run Code Online (Sandbox Code Playgroud)

if-else您的原始代码中不需要。