繁体   English   中英

python 根据键值过滤字典列表

[英]python filter list of dictionaries based on key value

我有一个字典列表,每个字典都有一个键(比方说)“type”,它可以有'type1''type2'等值。我的目标是将这些字典过滤到相同字典的列表中但只有某种“类型”的。 我想我只是在努力理解list/dictionary

所以示例列表如下所示:

exampleSet = [{'type':'type1'},{'type':'type2'},{'type':'type2'}, {'type':'type3'}]

我有一个键值列表。 比方说:

keyValList = ['type2','type3']

预期的结果列表如下所示:

expectedResult = [{'type':'type2'},{'type':'type2'},{'type':'type3'}]

我知道我可以用一组 for 循环来做到这一点。 我知道必须有一个更简单的方法。 我发现这个问题有很多不同的风格,但没有一个真正符合要求并回答了这个问题。 我会尝试回答……但它们并没有那么令人印象深刻。 可能最好让它开放。 任何帮助将不胜感激。

您可以尝试列表压缩

>>> exampleSet = [{'type':'type1'},{'type':'type2'},{'type':'type2'}, {'type':'type3'}]
>>> keyValList = ['type2','type3']
>>> expectedResult = [d for d in exampleSet if d['type'] in keyValList]
>>> expectedResult
[{'type': 'type2'}, {'type': 'type2'}, {'type': 'type3'}]

另一种方法是使用filter

>>> list(filter(lambda d: d['type'] in keyValList, exampleSet))
[{'type': 'type2'}, {'type': 'type2'}, {'type': 'type3'}]

使用filter ,或者如果在字典的数量exampleSet太高,使用ifilter的的itertools模块。 它会返回一个迭代器,而不是一次用整个列表填满系统的内存:

from itertools import ifilter
for elem in ifilter(lambda x: x['type'] in keyValList, exampleSet):
    print elem

从这篇文章中尝试了一些答案,我测试了每个答案的表现。

正如我最初的猜测,到目前为止, 列表理解速度更快filterlist方法次之, pandas排名第三。

定义的变量:

import pandas as pd

exampleSet = [{'type': 'type' + str(number)} for number in range(0, 1_000_000)]

keyValList = ['type21', 'type950000']


第一 - list comprehension

%%timeit
expectedResult = [d for d in exampleSet if d['type'] in keyValList]

每个循环 60.7 ms ± 188 µs(7 次运行的平均值 ± 标准偏差,每次 10 次循环)

2nd - filterlist

%%timeit
expectedResult = list(filter(lambda d: d['type'] in keyValList, exampleSet))

每个循环 94 ms ± 328 µs(7 次运行的平均值 ± 标准偏差,每次 10 次循环)

第三名—— pandas

%%timeit
df = pd.DataFrame(exampleSet)
expectedResult = df[df['type'].isin(keyValList)].to_dict('records')

每个循环 336 ms ± 1.84 ms(7 次运行的平均值 ± 标准偏差,每个循环 1 次)


附带说明一下,使用pandas来处理dict并不是一个好主意,因为pandas.DataFrame基本上是一个消耗更多内存的dict ,如果你最终不打算使用数据帧,那么它就是低效的。

filter the list of dictionaries based on key-value pairs<\/code>通用方法<\/strong>

def get_dic_filter_func(**kwargs):
    """Func to be used for map/filter function,
    returned func will take dict values from kwargs keys and compare resulted dict with kwargs"""
    def func(dic):
        dic_to_compare = {k: v for k, v in dic.items() if k in kwargs}
        return dic_to_compare == kwargs
    return func


def filter_list_of_dicts(list_of_dicts, **kwargs):
    """Filter list of dicts with key/value pairs
    in result will be added only dicts which has same key/value pairs as in kwargs """
    filter_func = get_dic_filter_func(**kwargs)
    return list(filter(filter_func, list_of_dicts))

这种类型的过滤在 Pandas 中很容易进行,尤其是在很多情况下,字典列表作为 Pandas 数据框开始时效果更好。

import pandas as pd

exampleSet = [{'type':'type1'}, {'type':'type2'}, {'type':'type2'}, {'type':'type3'}]
keyValList = ['type2', 'type3']

df = pd.DataFrame(my_list)
df[df['type'].isin(keyValList)]

结果是:

    type
1   type2
2   type2
3   type3

并根据OP的需要以字典形式取回它:

expectedResult = df[df['type'].isin(keyValList)].to_dict('records')
# the result will be [{'type': 'type2'}, {'type': 'type2'}, {'type': 'type3'}]

暂无
暂无

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

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