2015-05-17 79 views
3

我有一个词典的列表。每个字典都有几个键值和一个任意的(但重要的)键值对。例如如何删除列表中的重复字典,忽略字典键?

thelist = [ 
    {"key" : "value1", "k2" : "va1", "ignore_key" : "arb1"}, 
    {"key" : "value2", "k2" : "va2", "ignore_key" : "arb11"}, 
    {"key" : "value2", "k2" : "va2", "ignore_key" : "arb113"} 
] 

我想删除重复的字典,以便只忽略非“忽略键”值。我已经看到了related question - 但它只考虑完全相同的字迹。有没有办法删除几乎重复,使上述数据变成

thelist = [ 
    {"key" : "value1", "k2" : "va1", "ignore_key" : "arb1"}, 
    {"key" : "value2", "k2" : "va2", "ignore_key" : "arb11"} 
] 

重复的哪一个被忽略并不重要。我怎样才能做到这一点?

+0

是你的价值观总是可哈希? – DSM

+0

感谢您的回复。对不起 - 示例情况并不明确。有多个键值对,只有一个键可以忽略。 – user4467853

+0

@DSM是的,值始终是可散列的(文本和日期时间对象)。 – user4467853

回答

0

而不是使用一个列表中的字典,你可以使用字典的字典。你的每一个字典的关键价值将是主要字典的关键。

像这样:

thedict = {} 

thedict["value1"] = {"ignore_key" : "arb1", ...} 
thedict["value2"] = {"ignore_key" : "arb11", ...} 

因为字典不允许重复键你的问题就不存在了。

1

出发与你原来的列表:

thelist = [ 
    {"key" : "value1", "ignore_key" : "arb1"}, 
    {"key" : "value2", "ignore_key" : "arb11"}, 
    {"key" : "value2", "ignore_key" : "arb113"} 
] 

创建一组,并填充它,而过滤列表。

uniques, theNewList = set(), [] 
for d in theList:] 
    cur = d["key"] # Avoid multiple lookups of the same thing 
    if cur not in uniques: 
     theNewList.append(d) 
    uniques.add(cur) 

最后,重命名名单:

theList = theNewList 
5

保持一组看到值的key并删除具有相同值的任何字典:

st = set() 

for d in thelist[:]: 
    vals = d["key"],d["k2"] 
    if vals in st: 
     thelist.remove(d) 
    st.add(vals) 
print(thelist) 

[{'k2': 'va1', 'ignore_key': 'arb1', 'key': 'value1'}, 
{'k2': 'va2', 'ignore_key': 'arb11', 'key': 'value2'}] 

如果值总是分组,你可以使用keyvalue来分组并得到每组的第一个字典:

from itertools import groupby 
from operator import itemgetter 
thelist[:] = [next(v) for _, v in groupby(thelist,itemgetter("key","k2"))] 
print(thelist)] 

print(thelist) 
[{'key': 'value1', 'k2': 'va1', 'ignore_key': 'arb1'}, 
{'key': 'value2', 'k2': 'va2', 'ignore_key': 'arb11'}] 

或者使用类似于DSM的回答发电机修改原来的列表,而无需复制:

def filt(l): 
    st = set() 
    for d in l: 
     vals = d["key"],d["k2"] 
     if vals not in st: 
      yield d 
     st.add(vals) 


thelist[:] = filt(thelist) 

print(thelist) 

[{'k2': 'va1', 'ignore_key': 'arb1', 'key': 'value1'}, 
{'k2': 'va2', 'ignore_key': 'arb11', 'key': 'value2'}] 

如果你不关心哪个傻瓜被去除了刚刚使用了反转:

st = set() 

for d in reversed(thelist): 
    vals = d["key"],d["k2"] 
    if vals in st: 
     thelist.remove(d) 
    st.add(vals) 
print(thelist) 

要忽略所有栏ignore_key使用groupby:

from itertools import groupby 

thelist[:] = [next(v) for _, v in groupby(thelist, lambda d: 
       [val for k, val in d.items() if k != "ignore_key"])] 
print(thelist) 
[{'key': 'value1', 'k2': 'va1', 'ignore_key': 'arb1'}, 
{'key': 'value2', 'k2': 'va2', 'ignore_key': 'arb11'}] 
2

You c乌尔德硬塞东西放到一两行,但我认为这只是清洁编写一个函数:

def f(seq, ignore_keys): 
    seen = set() 
    for elem in seq: 
     index = frozenset((k,v) for k,v in elem.items() if k not in ignore_keys) 
     if index not in seen: 
      yield elem 
      seen.add(index) 

这给

>>> list(f(thelist, ["ignore_key"])) 
[{'ignore_key': 'arb1', 'k2': 'va1', 'key': 'value1'}, 
{'ignore_key': 'arb11', 'k2': 'va2', 'key': 'value2'}] 

这里假设你的价值观是哈希的。 (如果他们不是,那么相同的代码将与seen = []seen.append(index)一起使用,虽然它对长列表的性能不佳。)

0

不改变thelist

result = [] 
seen = set() 
thelist = [ 
    {"key" : "value1", "ignore_key" : "arb1"}, 
    {"key" : "value2", "ignore_key" : "arb11"}, 
    {"key" : "value2", "ignore_key" : "arb113"} 
] 

for item in thelist: 
    if item['key'] not in seen: 
     result.append(item) 
     seen.add(item['key']) 

print(result) 
0

创建了一套独特的价值观和核对(&更新)认为:

values = {d['key'] for d in thelist} 
newlist = [] 

for d in thelist: 
    if d['key'] in values: 
     newlist.append(d) 
     values -= {d['key']} 

thelist = newlist 
0

您可以通过使用一个适应accepted answer到链接的问题字典,而不是一组删除重复。

下面首先建立一个临时词典的键是在每个字典项目的在thelist一个元组除外,其被保存为与每个这些键中的相关联的值忽略一个。这样做可以消除重复项,因为它们将成为相同的项,但仍保留忽略的项和忽略的值(最后一项或只有一项)。

第二步创建thelist,通过创建由每个键的组合以及临时字典中项目的相关值组成的字典来重新创建thelist

你可以,如果你想这两个步骤合并成一个完全不可读的一行...

thelist = [ 
    {"key" : "value1", "k2" : "va1", "ignore_key" : "arb1"}, 
    {"key" : "value2", "k2" : "va2", "ignore_key" : "arb11"}, 
    {"key" : "value2", "k2" : "va2", "ignore_key" : "arb113"} 
] 

IGNORED = "ignore_key" 
temp = dict((tuple(item for item in d.items() if item[0] != IGNORED), 
      (IGNORED, d.get(IGNORED))) for d in thelist) 
thelist = [dict(key + (value,)) for key, value in temp.iteritems()] 

for item in thelist: 
    print item 

输出:

{'ignore_key': 'arb1', 'k2': 'va1', 'key': 'value1'} 
{'ignore_key': 'arb113', 'k2': 'va2', 'key': 'value2'}