使用lambda过滤字典列表中的字典值并在python中过滤

时间:2018-01-10 16:21:55

标签: python dictionary lambda filter list-comprehension

我有一个字典列表如下:

l = [{'abc': 'def'}, {'ghi': 'jul'}, {'Name': 'my-name'}]

我想获得具有键'名称'的词典的价值。 最初我写了一个函数如下:

def get_json_val(l, key):
    for item in l:
        for k, v in item.iteritems():
            if k == key:
                return v

但我想在一行中使用lambda和filter进行操作。所以,我尝试如下过滤字典:

name_lst = filter(lambda item: (k == 'Name' for k in item.iteritems()), l)

它再次显示整个列表。有没有办法只使用lambda和filter获取值(不是字典)?提前致谢

编辑1: 在第一个函数中,l是list和' Name'作为关键传递。

5 个答案:

答案 0 :(得分:1)

你为什么要对你的词典进行迭代?这违背了目的。只是做

[d for d in l if key in d]

或者如果您觉得使用lambda和过滤器有些强迫:

filter(lambda d: key in d, l)

注意,这些返回列表而不是相应的值。如果你想要这个值,你必须索引到列表中。简单地说,使用循环可能是最合理的方法,只是不要迭代你的dict:

def f(key, l):
    for d in l:
        if key in d:
            return d[key]

答案 1 :(得分:1)

看到你的初始代码,这应该做同样的事情

>>> l = [{'abc': 'def'}, {'ghi': 'jul'}, {'Name': 'my-name'}]
>>> [i["Name"] for i in l if "Name" in i][0]
'my-name'

你的代码只返回第一次出现。使用我的方法,也可能如果你使用过滤器,你将得到(第一个)所有出现的列表,而不是只得到第一个(如果有的话)。这会使它不那么“高效”恕我直言,所以我可能会将你的代码更改为更像这样的东西:

def get_json_val(l, key):
    for item in l:
        if not key in item: continue
        return item[key]

答案 2 :(得分:0)

l = [{'abc': 'def'}, {'ghi': 'jul'}, {'Name': 'my-name', "no-name": "bbb"}]

我能够以这种方式做到这一点,

print filter(lambda item: item, map(lambda item: item.get("Name"), l))

如果我打破这个。

首先检查项目是否在dict中?

fna = lambda item: item.get("Name")

然后将dict的列表映射到上面的函数。

map(fna, l)

以上列表将打印

  

[无,无,'我的名字']

现在我们需要消除所有的无。我正在使用filter以下函数

fnb = lambda item: item

现在,如果你把所有内容放在一起,你就可以将代码放在一行中。

答案 3 :(得分:0)

这是一种简单的方法,可以在没有lambdas或过滤器或其他任何东西的情况下完成。只需将字典列表合并到一个字典中,然后使用它。

l = [{'abc': 'def'}, {'ghi': 'jul'}, {'Name': 'my-name'}]
k = {m.keys()[0] : m[m.keys()[0]] for m in l}['Name']

请注意,这不会改变l。

的结构

答案 4 :(得分:0)

不要低估dict.get()的力量。接下来是对先前答案的简化。在这种情况下,不需要map。对于列表:

l = [{'abc': 'def'}, {'ghi': 'jul'}, {'Name': 'my-name'}]

以下内容产生了具有键'Name'的词典列表:

filtered = list(filter(lambda x: x.get('Name'), l))

从这里,您可以检索列表中所有项目的名称值:

values = [x['Name'] for x in filtered]

如果只有一个目标(如您的示例),则将其全部包裹在一行中,如下所示:

name = list(filter(lambda x: x.get('Name'), l))[0]['Name']