2

我已经看到了一些类似的答案,但是我找不到针对这种情况的特定内容:

我有一个这样的字典列表:

[
 {"element":Bla, "version":2, "date":"12/04/12"},
 {"element":Bla, "version":2, "date":"12/05/12"},
 {"element":Bla, "version":3, "date":"12/04/12"}
]

实际的字典有许多其他键,但我想要做的是删除所有具有完全相同键对值的条目,日期除外。也就是说,删除所有重复项(这些重复项并不是真正的重复项,因为只有日期不同)。在这种情况下,我期望得到的是:

[
 {"element":Bla, "version":2, "date":"12/04/12"},
 {"element":Bla, "version":3, "date":"12/04/12"}
]
4

5 回答 5

6

您说问题中未提及的字典中有很多其他键。

这是O(n)执行您需要的算法:

>>> seen = set()
>>> result = []
>>> for d in dicts:
...     h = d.copy()
...     h.pop('date')
...     h = tuple(h.items())
...     if h not in seen:
...         result.append(d)
...         seen.add(h)

>>> pprint(result)
[{'date': '12/04/12', 'element': 'Bla', 'version': 2},
 {'date': '12/04/12', 'element': 'Bla', 'version': 3}]

h是字典的副本。date键从其中删除pop

然后tuple被创建为可以添加到的可散列类型set

如果h以前从未见过,我们将其附加到result并添加到seen. seen对isO(1)和查找 ( h not in seen)的补充。

最后,仅包含定义值result方面的唯一元素。h

于 2013-03-19T22:56:26.583 回答
3

你可以使用 " unique_everseen" recipe fromitertools创建一个新的list.

list(unique_everseen(original_list, key=lambda e: '{element}@{version}'.format(**e)))

如果您的“键”需要比lambda我写的更宽(以容纳更多值),那么可能值得提取到函数中:

def key_without_date(element):
    return '@'.join(["{}".format(v) for k,v in element.iteritems() if k != 'date'])

list(unique_everseen(original_list, key=key_without_date))
于 2013-03-19T22:50:32.567 回答
1

Pandas 可以快速解决这个问题:

import pandas as pd
Bla = "Bla"
d = [
{"element":Bla, "version":2, "date":"12/04/12"},
{"element":Bla, "version":2, "date":"12/05/12"},
{"element":Bla, "version":3, "date":"12/04/12"}
]
df = pd.DataFrame(d)
df[~df.drop("date", axis=1).duplicated()]

输出:

       date element  version
0  12/04/12     Bla        2
2  12/04/12     Bla        3
于 2013-03-19T22:56:16.227 回答
1

Apologies for terrible variable names. There is probably a cleaner way but this should work

seen = {(item["element"], item["version"]): False for item in mylist}

output = []
for item in mylist:
    item_key = (item["element"], item["version"])
    if not seen[item_key]:
        output.append(item)
        seen[item_key] = True
于 2013-03-19T22:50:17.547 回答
0

这有效:

LoD=[
{"element":'Bla', "version":2, 'list':[1,2,3], "date":"12/04/12"},
{"element":'Bla', "version":2, 'list':[1,2,3], "date":"12/05/12"},
{"element":'Bla', "version":3, 'list':[1,2,3], "date":"12/04/12"}
]

LoDcopy=[]
seen=set()


for d in LoD:
    dc=d.copy()
    del dc['date']
    s=dc.__str__()
    if s in seen: continue
    seen.add(s)
    LoDcopy.append(d)    

print LoDcopy 

印刷:

[{'date': '12/04/12', 'version': 2, 'list': [1, 2, 3], 'element': 'Bla'}, 
 {'date': '12/04/12', 'version': 3, 'list': [1, 2, 3], 'element': 'Bla'}]
于 2013-03-19T23:13:32.470 回答