作者:于昕会_445 | 来源:互联网 | 2023-01-31 12:49
有一个字典列表我需要迭代并过滤符合条件的字典,然后只返回key1下的值.我正在使用过滤器,如下所示:
res = list(filter(lambda x: x["key1"] if ["key2"] == criterion else False, list_of_dicts))
迭代器可以正常返回那些符合标准的结果.但它返回整个字典而不仅仅是x["key1"]
.我认为它与过滤器有关但却没有任何线索.
Q1:有人可以解释为什么它返回整个dict而不是key1下的值吗?
Q2:是否有一种解决方法使过滤器只返回key1下的值?
PS通过列表理解这样做是没有问题的:
res = [i["key1"] for i in list_of_dicts if i["key2"] == criterion]
但我只是好奇为什么过滤器不会返回i["key1"]
.
1> Martijn Piet..:
过滤与映射不同.过滤根据您的标准选择,是/否决定是否包含您的一个值.
事实上,你正在过滤两者key2
和真值key1
; 如果值的值key1
被设置为None
或者是0
另一个假值,那么你也会删除那个我认为你不想要的特定字典.
您想要过滤和映射,因此从通过过滤器的字典中提取正确的密钥.这实际上最好用列表理解来完成:
res = [x["key1"] for x in list_of_dicts if ["key2"] == criterion]
filter()
如果必须的话,你仍然可以使用它,但是你需要添加一个map()
调用来实际进行映射:
res = list(map(lambda x: x["key1"], filter(lambda x: ["key2"], list_of_dicts)))
但正如你所注意到的那样,这很快就会变得冗长和不可读.您可以使用operator.itemgetter()
对象来替换lambda
s:
from operator import itemgetter
res = list(map(itemgetter("key1"), filter(lambda d: d["key2"] == condition, list_of_dicts)))
但可读性并没有太大提高.
@new_to_coding:它更快,因为列表推导循环完全作为字节码解释步骤执行,包括过滤器测试和提取表达式.这里是`itemgetter()`和`map()`和`filter()`的组合,它是真正的速度恶魔,*所有的执行*完全在C代码中完成,在解释器循环之外.
@new_to_coding:我确实犯了一个错误; 过滤器必须测试与条件的相等性,此时性能提升会减弱.
2> Willem Van O..:
过滤器只是过滤:它将可迭代的输入作为输入,并生成与满足标准的项目的可互换性.
你想要的是一个额外的map
ping:
from operator import itemgetter
key1 = itemgetter('key1')
res = list(map(key1,filter(lambda x: ["key2"] == criterion, list_of_dicts)))
请注意,您不需要x['key1'] if ... else False
在标准中使用:filter(..)
将简单地评估函数,并检查结果的真实性.如果是True
,它将发出该项目,否则它将忽略该项目.