筛选多个键集上的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] ]