2013-02-08 177 views
2

我需要一点功课帮助。我必须编写一个将多个字典组合成新字典的函数。如果一个键不止出现一次;在新字典中对应于该键的值应该是唯一列表。作为一个例子,这是我到目前为止有:Python删除组合字典列表中的重复值

f = {'a': 'apple', 'c': 'cat', 'b': 'bat', 'd': 'dog'} 
g = {'c': 'car', 'b': 'bat', 'e': 'elephant'} 
h = {'b': 'boy', 'd': 'deer'} 
r = {'a': 'adam'} 

def merge(*d): 
    newdicts={} 
    for dict in d: 
     for k in dict.items(): 
      if k[0] in newdicts: 
       newdicts[k[0]].append(k[1]) 
      else: 
       newdicts[k[0]]=[k[1]] 
    return newdicts 

combined = merge(f, g, h, r) 
print(combined) 

输出看起来像:

{“一”:“苹果”,“亚当”],“C”:“猫” ,'car'],'b':['bat','bat','boy'],'e':['elephant'],'d':['dog','deer']}

在'b'键下,'蝙蝠'出现两次。我如何删除重复项?

我式过滤器,拉姆达看,但我无法弄清楚如何与使用(也许B/C它在字典的名单?)

任何帮助,将不胜感激。并且预先感谢您的帮助!

回答

4

添加之前列表里面的元素只是测试: -

for k in dict.items(): 
    if k[0] in newdicts: 
     if k[1] not in newdicts[k[0]]: # Do this test before adding. 
      newdicts[k[0]].append(k[1]) 
    else: 
     newdicts[k[0]]=[k[1]] 

而且,由于要在value列表只是独特的元素,那么你可以只使用一个Set的值来代替。此外,您可以在这里使用defaultdict,这样您就不必在添加之前测试关键存在。

另外,不要使用内置的作为你的变量名称。而不是dict一些其他变量。

所以,你可以修改你的merge方法:

from collections import defaultdict 

def merge(*d): 
    newdicts = defaultdict(set) # Define a defaultdict 
    for each_dict in d: 

     # dict.items() returns a list of (k, v) tuple. 
     # So, you can directly unpack the tuple in two loop variables. 
     for k, v in each_dict.items(): 
      newdicts[k].add(v) 

    # And if you want the exact representation that you have shown 
    # You can build a normal dict out of your newly built dict. 
    unique = {key: list(value) for key, value in newdicts.items()} 
    return unique 
+0

感谢您对您的解释/评论提供非常好的/简单的解决方案。真的很感谢,因为我正在学习。 – JJoseph

+0

@JJoseph ..不客气:) –

1

在你的for循环补充一点:

for dict in d: 
    for k in dict.items(): 
     if k[0] in newdicts: 
      # This line below 
      if k[1] not in newdicts[k[0]]: 
       newdicts[k[0]].append(k[1]) 
     else: 
      newdicts[k[0]]=[k[1]] 

这可以确保副本未添加

2
>>> import collections 
>>> import itertools 
>>> uniques = collections.defaultdict(set) 
>>> for k, v in itertools.chain(f.items(), g.items(), h.items(), r.items()): 
... uniques[k].add(v) 
... 
>>> uniques 
defaultdict(<type 'set'>, {'a': set(['apple', 'adam']), 'c': set(['car', 'cat']), 'b':  set(['boy', 'bat']), 'e': set(['elephant']), 'd': set(['deer', 'dog'])}) 

注意结果是在一个集合中,而不是一个列表 - 这样计算效率更高。如果你想最终的形式是列表,那么你可以做到以下几点:

>>> {x: list(y) for x, y in uniques.items()} 

{“一”:“苹果”,“亚当”],“C”:“车”,“猫'','b':['boy','bat'],'e':['elephant'],'d':['deer','dog']}

0

当你想要独特元素:

def merge_dicts(*d): 
    result={} 
    for dict in d: 
     for key, value in dict.items(): 
      result.setdefault(key, set()).add(value) 
    return result 

尽量避免使用索引;改为解包元组。