Python 从列表中的嵌套词典中删除重复项

Python 从列表中的嵌套词典中删除重复项,python,dictionary,Python,Dictionary,快速和非常基本的新手问题 如果我有这样的词典列表: L = [] L.append({"value1": value1, "value2": value2, "value3": value3, "value4": value4}) L = [{"value1": fssd, "value2": dsfds, "value3": abcd, "value4": gk}, {"value1": asdasd, "value2": asdas, "value3": dafdd, "value

快速和非常基本的新手问题

如果我有这样的词典列表:

L = []
L.append({"value1": value1, "value2": value2, "value3": value3, "value4": value4})
L = [{"value1": fssd, "value2": dsfds, "value3": abcd, "value4": gk},
    {"value1": asdasd, "value2": asdas, "value3": dafdd, "value4": sdfsdf},
    {"value1": sdfsf, "value2": sdfsdf, "value3": abcd, "value4": gk},
    {"value1": asddas, "value2": asdsa, "value3": abcd, "value4": gk},
    {"value1": asdasd, "value2": dskksks, "value3": ldlsld, "value4": sdlsld}]
L = [{"value1": fssd, "value2": dsfds, "value3": abcd, "value4": gk},
    {"value1": asdasd, "value2": asdas, "value3": dafdd, "value4": sdfsdf},
    {"value1": asdasd, "value2": dskksks, "value3": ldlsld, "value4": sdlsld}
假设存在多个条目,其中value3和value4与其他嵌套字典相同。如何快速轻松地查找和删除那些重复的词典

维护秩序并不重要

谢谢

编辑:

如果有五个输入,如下所示:

L = []
L.append({"value1": value1, "value2": value2, "value3": value3, "value4": value4})
L = [{"value1": fssd, "value2": dsfds, "value3": abcd, "value4": gk},
    {"value1": asdasd, "value2": asdas, "value3": dafdd, "value4": sdfsdf},
    {"value1": sdfsf, "value2": sdfsdf, "value3": abcd, "value4": gk},
    {"value1": asddas, "value2": asdsa, "value3": abcd, "value4": gk},
    {"value1": asdasd, "value2": dskksks, "value3": ldlsld, "value4": sdlsld}]
L = [{"value1": fssd, "value2": dsfds, "value3": abcd, "value4": gk},
    {"value1": asdasd, "value2": asdas, "value3": dafdd, "value4": sdfsdf},
    {"value1": asdasd, "value2": dskksks, "value3": ldlsld, "value4": sdlsld}
输出应如下所示:

L = []
L.append({"value1": value1, "value2": value2, "value3": value3, "value4": value4})
L = [{"value1": fssd, "value2": dsfds, "value3": abcd, "value4": gk},
    {"value1": asdasd, "value2": asdas, "value3": dafdd, "value4": sdfsdf},
    {"value1": sdfsf, "value2": sdfsdf, "value3": abcd, "value4": gk},
    {"value1": asddas, "value2": asdsa, "value3": abcd, "value4": gk},
    {"value1": asdasd, "value2": dskksks, "value3": ldlsld, "value4": sdlsld}]
L = [{"value1": fssd, "value2": dsfds, "value3": abcd, "value4": gk},
    {"value1": asdasd, "value2": asdas, "value3": dafdd, "value4": sdfsdf},
    {"value1": asdasd, "value2": dskksks, "value3": ldlsld, "value4": sdlsld}
测试

list = [{"value1": 'fssd', "value2": 'dsfds', "value3": 'abcd', "value4": 'gk'},
{"value1": 'asdasd', "value2": 'asdas', "value3": 'dafdd', "value4": 'sdfsdf'},
{"value1": 'sdfsf', "value2": 'sdfsdf', "value3": 'abcd', "value4": 'gk'},
{"value1": 'asddas', "value2": 'asdsa', "value3": 'abcd', "value4": 'gk'},
{"value1": 'asdasd', "value2": 'dskksks', "value3": 'ldlsld', "value4": 'sdlsld'}]

对我来说很好:)

这是一个字典列表,但是,假设列表中有更多的字典

l = [ldict for ldict in l if ldict.get("value3") != value3 or ldict.get("value4") != value4]
但这就是你真正想做的吗?也许你需要改进你的描述

顺便说一句,不要使用
list
作为名称,因为它是Python内置程序的名称

编辑:假设您从一个字典列表开始,而不是一个每个字典都有一个字典列表的列表,每个字典列表应该适用于您的示例。如果这两个值中的任何一个都不存在,则它将不起作用,因此最好采用以下方式:

l = [ldict for ldict in l if not ( ("value3" in ldict and ldict["value3"] == value3) and ("value4" in ldict and ldict["value4"] == value4) )]
但它似乎仍然是一种不同寻常的数据结构

编辑:无需使用显式
get
s


此外,解决方案中总是存在权衡。如果没有更多的信息和实际测量,很难知道哪些性能权衡对问题最重要。但是,正如sez所说:“简单比复杂好”。

您可以使用临时数组来存储items dict。前面的代码在删除for循环中的项时被安装了错误

(v,r) = ([],[])
for i in l:
    if ('value4', i['value4']) not in v and ('value3', i['value3']) not in v:
        r.append(i)
    v.extend(i.items())
l = r
您的测试:

l = [{"value1": 'fssd', "value2": 'dsfds', "value3": 'abcd', "value4": 'gk'},
    {"value1": 'asdasd', "value2": 'asdas', "value3": 'dafdd', "value4": 'sdfsdf'},
    {"value1": 'sdfsf', "value2": 'sdfsdf', "value3": 'abcd', "value4": 'gk'},
    {"value1": 'asddas', "value2": 'asdsa', "value3": 'abcd', "value4": 'gk'},
    {"value1": 'asdasd', "value2": 'dskksks', "value3": 'ldlsld', "value4": 'sdlsld'}]
输出

{'value4': 'gk', 'value3': 'abcd', 'value2': 'dsfds', 'value1': 'fssd'}
{'value4': 'sdfsdf', 'value3': 'dafdd', 'value2': 'asdas', 'value1': 'asdasd'}
{'value4': 'sdlsld', 'value3': 'ldlsld', 'value2': 'dskksks', 'value1': 'asdasd'}
这里有一个方法:

keyfunc = lambda d: (d['value3'], d['value4'])

from itertools import groupby
giter = groupby(sorted(L, key=keyfunc), keyfunc)

L2 = [g[1].next() for g in giter]
print L2

如果我理解正确,您希望放弃原始列表中稍后出现的匹配,但不关心结果列表的顺序,因此:

(根据第2.5.2节进行测试)

在Python 2.6或3.*中:

import itertools
import pprint

L = [{"value1": "fssd", "value2": "dsfds", "value3": "abcd", "value4": "gk"},
    {"value1": "asdasd", "value2": "asdas", "value3": "dafdd", "value4": "sdfsdf"},
    {"value1": "sdfsf", "value2": "sdfsdf", "value3": "abcd", "value4": "gk"},
    {"value1": "asddas", "value2": "asdsa", "value3": "abcd", "value4": "gk"},
    {"value1": "asdasd", "value2": "dskksks", "value3": "ldlsld", "value4": "sdlsld"}]

getvals = operator.itemgetter('value3', 'value4')

L.sort(key=getvals)

result = []
for k, g in itertools.groupby(L, getvals):
    result.append(g.next())

L[:] = result
pprint.pprint(L)

在Python 2.5中几乎相同,只是在追加中必须使用g.next()而不是next(g)。

为了澄清,如果另一个字典中有匹配的键/值对,或者如果另一个字典中只有键(不一定是值)存在,是否要删除键/值对?是否只有键3和键4不能相同?如果一个键的值与另一个dict中另一个键的值匹配,会发生什么情况?另外,顺便说一句,将列表命名为
list
以外的名称,否则将覆盖内置名称空间中实际的
list
,以后不能调用
list()
函数
lst
list\
是相当常见的选择。是的,只需按3键和4键,其余的可以重复。我只是在列表中使用字典,因为它比在列表中使用列表更容易理解,这样你就可以调用l[“value1”],但那是另一个故事。现在你有了一个列表,每个列表都有一本字典。你确定你想在每本字典周围多加一组[]吗?你好,内德,谢谢你的输入,我已经在同一个列表的输入和输出中添加了一个示例,而且,在那个特定的示例中,我已经重命名了列表。谢谢。你的输出不正确。看看我的例子。无论如何谢谢你的尝试。你试过运行你的代码吗?它不符合OP的要求。有几个问题:(1)为什么要按相反的顺序遍历列表?(2) 为什么使用(d[“value3”]、d[“value4”])作为临时字典中的键?(3) 为什么在迭代期间将列表中的当前词典指定为临时词典的值?Hrm-做我的解释(我不确定),也匹配他的输出-虽然不是它的顺序,但他说保留它并不重要。我的解释是:当多个字典具有相同的(value3,value4)对时,只保留原始列表中的第一个这样的字典。而且,生成的dict列表不必具有相同的顺序。所以(1) 因此,原始列表中的第一个输入将“赢”并保留,(2)因为我认为这是唯一的,(3)因为字典是我为新列表提取的值。(在我的测试输出中,dict项目以相反的顺序打印,dict列表以不同的顺序打印,但因为他说“保持秩序并不重要”,这似乎在参数范围内。)回顾过去,我坚持我的解释。秩序似乎是唯一的争论点。请注意,如果OP的原始数据,比如说,将“abcd”的实例替换为“xkcd”,那么Alex的答案中的排序(一如既往地摇摆不定)这个问题的随机数据(甚至没有被引用)并没有表明它的顺序不是偶然事件——同样,特别是与“保持秩序不重要”相结合。“看起来你的答案是正确的,而且比亚历克斯的早了一个小时。我想,一旦一个问题得到5到6个以上的答案,很容易被遗漏。我想,成为第一对或最后一对可能会有所帮助。没什么大不了的,不过谢谢你提醒我。:)在python3.3中运行此操作并获得错误
AttributeError:'itertools.\u gropper'对象没有属性'next'
任何线索?