简体   繁体   English

在python中使用lambda和filter从字典列表中过滤字典值

[英]Filtering a dictionary value from a list of dictionary using lambda and filter in python

I have a list of dictionaries as below:我有一个字典列表如下:

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

I want to get the value of the dictionary that has the key 'Name' Initially I wrote a function as below:我想获取具有键“名称”的字典的值最初我编写了一个函数,如下所示:

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

But I want to do it using lambdas and filter in a single line.但我想在一行中使用 lambdas 和 filter 来做到这一点。 So, I tried as below to filter out the dictionary:所以,我尝试如下过滤字典:

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

It is showing the whole list again.它再次显示整个列表。 Is there a way to get only the value (not dictionary) using lambdas and filter?有没有办法使用 lambdas 和过滤器只获取值(而不是字典)? Thanks in advance提前致谢

Edit 1: In the first function l is list and 'Name' is passed as key.编辑 1:在第一个函数中,l 是列表,“名称”作为键传递。

Why are you iterating over your dict?你为什么要迭代你的字典? That defeats the purpose.这违背了目的。 Just do就做

[d for d in l if key in d]

Or if you feel some compulsion to use lambda and filter:或者,如果您觉得有必要使用 lambda 和过滤器:

filter(lambda d: key in d, l)

Note, these return lists instead of the corresponding value.请注意,这些返回列表而不是相应的值。 If you want the value, you'll have to index into the list.如果您想要该值,则必须对列表进行索引。 Simply out, using a loop is probably the most reasonable approach, just don't iterate over your dict:简单地说,使用循环可能是最合理的方法,只是不要迭代你的字典:

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

Seeing your initial code, this should do the same thing看到你的初始代码,这应该做同样的事情

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

Your code returns only the first occurence.Using my approach, and probably also if you would use filter, you'll get (first) a list of all occurrences than only get the first (if any).您的代码仅返回第一次出现。使用我的方法,并且可能如果您使用过滤器,您将获得(第一个)所有事件的列表,而不是仅获得第一个(如果有)。 This would make it less "efficient" IMHO, so I would probably change your code to be something more like this:恕我直言,这会降低它的“效率”,因此我可能会将您的代码更改为更像这样:

def get_json_val(l, key):
    for item in l:
        if not key in item: continue
        return item[key]
l = [{'abc': 'def'}, {'ghi': 'jul'}, {'Name': 'my-name', "no-name": "bbb"}]

I was able to do it in this way,我能够以这种方式做到这一点,

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

if I break this down.如果我打破这个。

First check if item is in the dict or not?首先检查项目是否在字典中?

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

then map list of dict to above function.然后将 dict 列表映射到上述函数。

map(fna, l)

for above list it will print对于上面的列表,它将打印

[None, None, 'my-name'] [无,无,'我的名字']

Now we need to eliminate all the None.现在我们需要消除所有的 None。 I am using filter with following function我正在使用具有以下功能的filter

fnb = lambda item: item

Now if you put all together you have your code in single line.现在,如果你把所有东西放在一起,你的代码就在一行中。

Here is an easy way to do it without lambdas or filter or any of that stuff.这是一种无需 lambdas 或过滤器或任何此类内容的简单方法。 Just combine the list of dictionaries to one dictionary, then use that.只需将字典列表组合到一个字典中,然后使用它。

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

Note that this does not change the structure of l.请注意,这不会改变 l 的结构。

Don't underestimate the power of dict.get() .不要低估dict.get()的力量。 What follows is a simplification of a previous answer.以下是对先前答案的简化。 In this case, there is no need for map .在这种情况下,不需要map For the list:对于列表:

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

The following produces a list of dictionaries that have the key 'Name' :以下生成具有键'Name'的字典列表:

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

From here, you can retrieve the name values for all items in the list:从这里,您可以检索列表中所有项目的名称值:

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

If there is only one target, as in your example, wrap this all up in one line like this:如果只有一个目标,如您的示例中所示,请将其全部包装在一行中,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM