在Python中基于键(非键值)过滤字典列表

时间:2016-11-06 09:02:39

标签: python list dictionary filter

我想基于单个键过滤(不同的)词典列表,而不是此键所持有的值。

这是一个例子:

diclist_example=[{'animal': 'dog', 'legs': 'four'}, 
                {'tvshow': 'Game of Thrones','rating': 'good'},
                {'food': 'banana','color': 'yellow'},
                {'animal': 'sheep', 'legs': 'four'}, 
                {'tvshow': 'Gossip Girl','rating': 'bad'},
                {'food': 'pizza','color': 'red-ish'}]

这个问题是当我尝试使用'animal'值时,我得到一个KeyError,因为有些dictonaries不包含'animal'值。

我想生成一个新的词典列表,其中包含基于键的所有词典,例如,包含所有动物的列表,以及包含所有食物的列表的所有电视节目的列表。

5 个答案:

答案 0 :(得分:1)

您可以使用lambda函数来执行此操作,该函数使用列表推导过滤元素。此函数将返回所有相同元素的列表

getAllElementsWithSameKey = lambda key:[d for d in diclist_example if key in d]
getAllElementsWithSameKey('animal')

您可以使用

创建所有词典的列表
allElements = [getAllElementsWithSameKey(k) for k in ('animal','tvshow','food')]

答案 1 :(得分:0)

使用setSoTimeout(0)自动创建字典列表。

defaultdict

结果:

from collections import defaultdict

diclist_example=[{'animal': 'dog', 'legs': 'four'},
                {'tvshow': 'Game of Thrones','rating': 'good'},
                {'food': 'banana','color': 'yellow'},
                {'animal': 'sheep', 'legs': 'four'},
                {'tvshow': 'Gossip Girl','rating': 'bad'},
                {'food': 'pizza','color': 'red-ish'}]

diclist = defaultdict(list)
for l in diclist_example:
    for k in ('animal','food','tvshow'):
        if k in l:
            diclist[k].append(l)
            break

print(diclist)

答案 2 :(得分:0)

在使用if语句执行任何操作之前,应始终检查该值是否存在。

if myValue!=None: # or similar, depending on situation
    # do something

将它应用于您的示例:

def zipDict(dicts):
    allKeys = set(k for d in dicts for k in d.keys())
    return {k:[d[k] for d in dicts if (k in d)] for k in allKeys}
                                   ###########  

这是一个更详细的版本:

def zipDict(dicts):
    allKeys = set()
    for d in dicts:
        for key in d:
            allKeys.add(key)

    toReturn = {}
    for key in allKeys:
        toReturn[key] = []
        for d in dicts:
            if key in d: # THE GUARDIAN IF STATEMENT THAT PROTECTS YOU
                toReturn[key].append(d[key])

    return toReturn

旁注:对于可能偶然发现这篇文章的其他用户,这里有一个更有效的方法:你应该遍历dicts,而不是allKeys,否则你的算法是O(#keys * #dicts),而不是O (N):

def zipDict(dicts):
    R = {}
    for d in dicts:
        for k,v in d.items():
            if not k in R:  # A PROTECTIVE IF STATEMENT
                R[k] = []
            R[k].append(v)
    return R

您可以使用defaultdict使代码更精确:

def zipDict(dicts):
    R = defaultdict(list)
    for d in dicts:
        for k,v in d.items():
            R[k].append(v)
    return dict(R)

答案 3 :(得分:0)

Ex [硬编码]:

l = [dicict_example中dict_elt的dict_elt如果' animal'在dict_elt]

答案 4 :(得分:0)

您还可以尝试以下方法:

filter(lambda x: x["animal"] if "animal" in x else None, diclist_example)