筛选多个键集上的python词典列表

筛选多个键集上的python词典列表,python,Python,假设我有字典: my_dict = [ {'first': 'James', 'middle': 'Smith', 'last': 'Joule'}, {'first': 'James', 'middle': 'smith', 'last': 'joule'}, {'first': 'Christian', 'middle': 'Edward', 'last': 'Doppler'}, {'first': 'Robert', 'm

假设我有字典:

my_dict = [
        {'first': 'James', 'middle': 'Smith', 'last': 'Joule'}, 
        {'first': 'James', 'middle': 'smith', 'last': 'joule'},
        {'first': 'Christian', 'middle': 'Edward', 'last': 'Doppler'},
        {'first': 'Robert', 'middle': 'Edward', 'last': 'Antonio'},
        {'first': 'Robert', 'middle': 'edward', 'last': 'antonio'},
        {'first': 'Robert', 'middle': 'edwrd', 'last': 'Antonio'},
        {'first': 'James', 'middle': 'Jackson', 'last': 'harden'}, 
        {'first': 'James', 'middle': 'jackson', 'last': 'Harden'},
      ]
我有一个叫做“钥匙”的清单:

keys = ["first", "last"]
我想根据键中的每个值筛选myDict,这将导致

filtered_dict = [
        {'first': 'James', 'middle': 'Smith', 'last': 'Joule'}, 
        {'first': 'Christian', 'middle': 'Edward', 'last': 'Doppler'},
        {'first': 'Robert', 'middle': 'Edward', 'last': 'Antonio'},
        {'first': 'James', 'middle': 'Jackson', 'last': 'harden'}
      ]
正如您在my_dict list中的list dictionary中所看到的,重复的dict值将从列表中删除或过滤掉,并且在过滤后的输出中仅获取该dict实例的第一个条目


如果两个键的值相同,我需要删除重复项


Python中的字典/列表理解有没有一种简单的方法?有没有其他更快的方法来实现这一点?

一种解决方案是使用如下所示的pandas数据帧。这将允许像CSV文件一样删除重复行。不过,这并没有考虑大小写敏感度,如果您需要不区分大小写的重复删除,那将是另一种方法。但这很有效

import pandas as pd

my_dict = [
    {'first': 'James', 'middle': 'Smith', 'last': 'Joule'},
    {'first': 'James', 'middle': 'smith', 'last': 'joule'},
    {'first': 'Christian', 'middle': 'Edward', 'last': 'Doppler'},
    {'first': 'Robert', 'middle': 'Edward', 'last': 'Antonio'},
    {'first': 'Robert', 'middle': 'edward', 'last': 'antonio'},
    {'first': 'Robert', 'middle': 'edwrd', 'last': 'Antonio'},
    {'first': 'James', 'middle': 'Jackson', 'last': 'harden'},
    {'first': 'James', 'middle': 'jackson', 'last': 'Harden'}
]


keys = ["first", "last"]

df = pd.DataFrame(my_dict)

df = df.drop_duplicates(keep="first")
print(df)

首先,将其称为
my_list
,而不是
my_dict

my_list = [
    {'first': 'James', 'middle': 'Smith', 'last': 'Joule'},
    {'first': 'James', 'middle': 'smith', 'last': 'joule'},
    {'first': 'Christian', 'middle': 'Edward', 'last': 'Doppler'},
    {'first': 'Robert', 'middle': 'Edward', 'last': 'Antonio'},
    {'first': 'Robert', 'middle': 'edward', 'last': 'antonio'},
    {'first': 'Robert', 'middle': 'edwrd', 'last': 'Antonio'},
    {'first': 'James', 'middle': 'Jackson', 'last': 'harden'},
    {'first': 'James', 'middle': 'jackson', 'last': 'Harden'}
]
keys = ["first", "last"]
然后,您可以通过以下理解实现您的目标:

import collections
temp = collections.OrderedDict([
    (
        tuple(e[k].lower() for k in keys),    # only some keys will determine duplicates
        e,
    )
    for e in my_list])

my_new_list = list(temp.values())
通过按名字和姓氏对元素进行分组,将排除重复项。稍后,如果需要,您只需再次将其转换到列表中

使用
OrderedDict
可以保留原始顺序

我还使用
.lower()
查找不区分大小写的重复项。

您可以使用
(x[“first”].lower,x[“last”].lower())
按进行分组,然后只提取分组值的第0个元素:

from itertools import groupby
# https://docs.python.org/3/library/itertools.html#itertools.groupby

my_dict = [
        {'first': 'James', 'middle': 'Smith', 'last': 'Joule'}, 
        {'first': 'James', 'middle': 'smith', 'last': 'joule'},
        {'first': 'Christian', 'middle': 'Edward', 'last': 'Doppler'},
        {'first': 'Robert', 'middle': 'Edward', 'last': 'Antonio'},
        {'first': 'Robert', 'middle': 'edward', 'last': 'antonio'},
        {'first': 'Robert', 'middle': 'edwrd', 'last': 'Antonio'},
        {'first': 'James', 'middle': 'Jackson', 'last': 'harden'}, 
        {'first': 'James', 'middle': 'jackson', 'last': 'Harden'},
      ]

keys = ["first","last"]

k = [list(data)[0] for key,data in groupby(my_dict, 
                                           key=lambda x: tuple(x[i].lower() for i in keys))]

print(k) 
输出:

[{'first': 'James', 'middle': 'Smith', 'last': 'Joule'}, 
 {'first': 'Christian', 'middle': 'Edward', 'last': 'Doppler'}, 
 {'first': 'Robert', 'middle': 'Edward', 'last': 'Antonio'}, 
 {'first': 'James', 'middle': 'Jackson', 'last': 'harden'}]

警告:

Groupby仅适用于连续键-如果在列表末尾有第三个
{'first':'James','middle':'Smith','last':'JOUle'}
他会得到自己的条目:

制作一个迭代器,从iterable返回连续的键和组
(来自doku,上面的链接)


如果您希望列表都在同一个组中,则需要先对列表进行排序,然后依次分组。

首先,请澄清您希望筛选不区分大小写的列表

用于过滤上下过滤器的python解决方案:

values = list(map(lambda x: set(i.lower() for i in x.values()), my_dict))
my_filter_list = [my_dict[i] for i,x in enumerate(values) if values.index(x)==i]

下面的解决方案不需要任何导入语句,并且能够区分大小写。它还只考虑“关键点”列表中提供的字段,并在匹配时忽略所有其他字段(在匹配时考虑所有字段,而不考虑“关键点”列表中的内容)

如果只想消除连续重复(如中),则必须按以下方式声明
filtered\u dict

filtered_dict = [ my_dict[i] for i,v in enumerate(fields) if i == 0 or v != fields[i-1] ]

列表有什么用?如果这两个键的值相同,我需要删除重复项。你应该要求列表理解,而不是字典理解,因为你正在构建列表。肯定有可能重复。我刚刚编辑了这个问题。我正在寻找任何pythonic,不需要我写一个单独的函数来检查循环中的每个函数。你是什么意思?是否应该区分大小写?关于区分大小写的规定是一个不同的问题/单独的问题。这也很有效。。谢谢你的回复,我也会记住这个方法
filtered_dict = [ my_dict[i] for i,v in enumerate(fields) if i == 0 or v != fields[i-1] ]