Python 根据密钥的唯一性从列表中删除重复的DICT
我的问题有点类似于这个问题:。本质上,我有一个字典列表,我想根据每个字典中两个或多个键的唯一组合从列表中删除重复项 假设我有以下词典列表:Python 根据密钥的唯一性从列表中删除重复的DICT,python,python-3.x,Python,Python 3.x,我的问题有点类似于这个问题:。本质上,我有一个字典列表,我想根据每个字典中两个或多个键的唯一组合从列表中删除重复项 假设我有以下词典列表: some_list_of_dicts = [ {'a': 1, 'b': 1, 'c': 1, 'd': 2, 'e': 4}, {'a': 1, 'b': 1, 'c': 1, 'd': 5, 'e': 1}, {'a': 1, 'b': 1, 'c': 1, 'd': 7, 'e': 8}, {'a': 1, 'b': 1, 'c': 1, 'd': 9
some_list_of_dicts = [
{'a': 1, 'b': 1, 'c': 1, 'd': 2, 'e': 4},
{'a': 1, 'b': 1, 'c': 1, 'd': 5, 'e': 1},
{'a': 1, 'b': 1, 'c': 1, 'd': 7, 'e': 8},
{'a': 1, 'b': 1, 'c': 1, 'd': 9, 'e': 6},
{'a': 1, 'b': 1, 'c': 2, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 3, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 4, 'd': 2, 'e': 3}
]
假设a,b,c的组合是唯一的;任何其他值都可以是它们想要的任何值,但这三个值的组合对于此列表来说必须是唯一的。我想先选择a、b和c中唯一的组合,保留该组合,并在组合相同的情况下丢弃所有其他组合
在通过一些remove_duplicates函数运行新列表后,新列表将如下所示:
new_list = [
{'a': 1, 'b': 1, 'c': 1, 'd': 2, 'e': 4},
{'a': 1, 'b': 1, 'c': 2, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 3, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 4, 'd': 2, 'e': 3}
]
我只想到了这个:
def remove_duplicates(old_list):
uniqueness_check_list = []
new_list = []
for item in old_list:
# The unique combination is 'a', 'b', and 'c'
uniqueness_check = "{}{}{}".format(
item["a"], item["b"], item["c"]
)
if uniqueness_check not in uniqueness_check_list:
new_list.append(item)
uniqueness_check_list.append(uniqueness_check)
return new_list
但这感觉不太像蟒蛇。它还有一个问题,我在函数中硬编码了哪些键必须是唯一的;如果我可以将其指定为函数本身的参数,那就更好了,但同样,我不确定这样做的最优雅的方式是什么。您可以使用dict理解从dict列表中以相反的顺序构造dict,以便任何唯一组合中的第一个的值优先。使用operator.itemgetter将唯一键作为元组获取。最后再次反转原始顺序:
from operator import itemgetter
list({itemgetter('a', 'b', 'c')(d): d for d in reversed(some_list_of_dicts)}.values())[::-1]
这将返回:
[{'a': 1, 'b': 1, 'c': 1, 'd': 2, 'e': 4},
{'a': 1, 'b': 1, 'c': 2, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 3, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 4, 'd': 2, 'e': 3}]
您可以使用dict理解从dict列表中按相反顺序构造dict,以便任何唯一组合中的第一个的值优先。使用operator.itemgetter将唯一键作为元组获取。最后再次反转原始顺序:
from operator import itemgetter
list({itemgetter('a', 'b', 'c')(d): d for d in reversed(some_list_of_dicts)}.values())[::-1]
这将返回:
[{'a': 1, 'b': 1, 'c': 1, 'd': 2, 'e': 4},
{'a': 1, 'b': 1, 'c': 2, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 3, 'd': 2, 'e': 3},
{'a': 1, 'b': 1, 'c': 4, 'd': 2, 'e': 3}]
借助跟踪重复项的函数,您可以使用一些列表理解:
def remove_duplicates(old_list, cols=('a', 'b', 'c')):
duplicates = set()
def is_duplicate(item):
duplicate = item in duplicates
duplicates.add(item)
return duplicate
return [x for x in old_list if not is_duplicate(tuple([x[col] for col in cols]))]
使用:
>>> remove_duplicates(some_list_of_dicts)
[
{'a': 1, 'c': 1, 'b': 1, 'e': 4, 'd': 2},
{'a': 1, 'c': 2, 'b': 1, 'e': 3, 'd': 2},
{'a': 1, 'c': 3, 'b': 1, 'e': 3, 'd': 2},
{'a': 1, 'c': 4, 'b': 1, 'e': 3, 'd': 2}
]
您还可以提供不同的列来输入:
>>> remove_duplicates(some_list_of_dicts, cols=('a', 'd'))
[
{'a': 1, 'c': 1, 'b': 1, 'e': 4, 'd': 2},
{'a': 1, 'c': 1, 'b': 1, 'e': 1, 'd': 5},
{'a': 1, 'c': 1, 'b': 1, 'e': 8, 'd': 7},
{'a': 1, 'c': 1, 'b': 1, 'e': 6, 'd': 9}
]
借助跟踪重复项的函数,您可以使用一些列表理解:
def remove_duplicates(old_list, cols=('a', 'b', 'c')):
duplicates = set()
def is_duplicate(item):
duplicate = item in duplicates
duplicates.add(item)
return duplicate
return [x for x in old_list if not is_duplicate(tuple([x[col] for col in cols]))]
使用:
>>> remove_duplicates(some_list_of_dicts)
[
{'a': 1, 'c': 1, 'b': 1, 'e': 4, 'd': 2},
{'a': 1, 'c': 2, 'b': 1, 'e': 3, 'd': 2},
{'a': 1, 'c': 3, 'b': 1, 'e': 3, 'd': 2},
{'a': 1, 'c': 4, 'b': 1, 'e': 3, 'd': 2}
]
您还可以提供不同的列来输入:
>>> remove_duplicates(some_list_of_dicts, cols=('a', 'd'))
[
{'a': 1, 'c': 1, 'b': 1, 'e': 4, 'd': 2},
{'a': 1, 'c': 1, 'b': 1, 'e': 1, 'd': 5},
{'a': 1, 'c': 1, 'b': 1, 'e': 8, 'd': 7},
{'a': 1, 'c': 1, 'b': 1, 'e': 6, 'd': 9}
]
我在Jupyter笔记本电脑中运行了%timeit,结果是:12.7µs±352 ns/循环平均值±标准偏差7次,每次100000次循环。另一个答案中的remove_duplicates函数给出了34.2µs±499 ns/循环平均值±标准偏差7次,每次10000次循环。我试图想出一个简单的答案,然后看到了这个答案。美好的同意!很好的回答@blhsingI在Jupyter笔记本电池中运行了%timeit,结果是:12.7µs±352 ns/循环平均值±标准偏差7次,每次100000次循环另一个回答中的remove_duplicates函数给出了34.2µs±499 ns/循环平均值±标准偏差7次,每次10000次循环。我试图想出一个简单的答案,然后看到了这个答案。美好的同意!回答得好@blhsing