Python在dict中删除一个键的重复值

时间:2015-01-15 15:14:27

标签: python dictionary duplicate-removal

我有这样的字典:

Files:
{'key1': ['path1', 'path1', 'path2', 'path1', 'path2'], 
'key2': ['f', 'f', 'f', 'f', 'f'], 
'key_file': ['file1', 'file1', 'file2', 'file1', 'file2']}

我想删除'key_file'中的所有重复值和其他键中的其他值('key1'和'key2')。

所需词典:

Files:
{'key1': ['path1', 'path2'], 
'key2': ['f', 'f'], 
'key_file': ['file1', 'file2']}

我找不到保留订单的解决方案,并删除了其他键中的每个重复项及其值。

非常感谢。

编辑:

'key2': ['f', 'f', 'f', 'f', 'f']

变为

'key2': ['f', 'f'],

因为有两个不同的文件。

我不想删除每个密钥中的每个重复项。 'path1'与'file1'相关,'path2'与'file2'相关,两种情况下key2中的'f'都与'file2'相关。实际上实际上有几个键,但这是我的最小例子。那是我的问题。我找到了几个删除每个副本的解决方案。

EDIT2:

也许我有点困惑。

每个键的长度与描述文件名(在key_file中),相应路径(在key1中)和其他一些描述字符串(在key2中等)相同。可能会发生相同的文件存储在不同的位置(路径),但我知道,如果文件名完全相同,则它是同一个文件。

基本上我正在寻找的是一个函数,它检测key_file的第二个值,文件名为file1,作为第一个值file1的副本,并从每个键中删除第二个值。值4(文件1)和5(文件2)相同。结果字典看起来就像我提到的那样。

我希望这能更好地解释它。

5 个答案:

答案 0 :(得分:2)

一种天真的方法:迭代键并将每个值添加到新的dict中:

>>> newFiles={'key1': [], 'key2':[], 'key_file':[]}
>>> for i,j in enumerate(Files['key_file']):
...   if j not in newFiles['key_file']:
...      for key in newFiles.keys():
...         newFiles[key].append(Files[key][i])
...
>>> newFiles
{'key2': ['1', '3'], 'key1': ['a', 'c'], 'key_file': ['file1', 'file2']}

使用OrderedDict:

>>> for j in OrderedDict.fromkeys(Files['key_file']):
...   i = Files['key_file'].index(j)
...   if j not in newFiles['key_file']:
...     for key in newFiles.keys():
...       newFiles[key].append(Files[key][i])
...
>>> newFiles
{'key2': ['1', '3'], 'key1': ['a', 'c'], 'key_file': ['file1', 'file2']}

注意:如果"文件"在key_file中始终具有相同的key_1key_2,有更好的方法。例如,使用zip

>>> z=zip(*Files.values())
>>> z
[('f', 'path1', 'file1'), ('f', 'path1', 'file1'), ('f', 'path2', 'file2'), ('f', 'path1', 'file1'), ('f', 'path2', 'file2')]
>>> OrderedDict.fromkeys(z)
OrderedDict([(('f', 'path1', 'file1'), None), (('f', 'path2', 'file2'), None)])
>>> list(OrderedDict.fromkeys(z))
[('f', 'path1', 'file1'), ('f', 'path2', 'file2')]
>>> zip(*OrderedDict.fromkeys(z))
[('file1', 'file2'), ('path1', 'path2'), ('f', 'f')]

答案 1 :(得分:1)

OrderedDict是最好的,因为它保留了订单

您可以将其添加到集合中,然后将其设为列表

实施例

for i in d:
    d[i] = list(set(d[i]))

答案 2 :(得分:1)

您可以使用collections.OrderedDict按字母顺序排列字典,set删除重复字词:

>>> d={'key1': ['path1', 'path1', 'path2', 'path1', 'path2'], 
... 'key2': ['f', 'f', 'f', 'f', 'f'], 
... 'key_file': ['file1', 'file1', 'file2', 'file1', 'file2']}
>>> from collections import OrderedDict
>>> OrderedDict(sorted([(i,list(set(j))) for i,j in d.items()], key=lambda t: t[0]))
OrderedDict([('key1', ['path2', 'path1']), ('key2', ['f']), ('key_file', ['file2', 'file1'])])

您需要使用set来删除重复项,然后根据键对项目进行排序,最后使字典保持排序使用OrderedDict

编辑:如果您希望所有值的长度与最大值相同,请使用以下命令:

>>> s=sorted([(i,list(set(j))) for i,j in d.items()], key=lambda t: t[0])
>>> M=max(map(len,[i[1] for i in s])
>>> f_s=[(i,j) if len(j)==M else (i,[j[0] for t in range(M)]) for i,j in s]
>>> f_s
[('key1', ['path2', 'path1']), ('key2', ['f', 'f']), ('key_file', ['file2', 'file1'])]
>>> OrderedDict(f_s)
OrderedDict([('key1', ['path2', 'path1']), ('key2', ['f', 'f']), ('key_file', ['file2', 'file1'])])

但如果你只想要任何值的前2个元素,你可以使用切片:

>>> OrderedDict(sorted([(i,j[:2]) for i,j in d.items()],key=lambda x: x[0])
... )
OrderedDict([('key1', ['path1', 'path1']), ('key2', ['f', 'f']), ('key_file', ['file1', 'file1'])])

答案 3 :(得分:0)

根据我的理解,似乎字典中不同列表中的相应值属于一起,而同一列表中的值彼此无关。在这种情况下,我建议使用不同的数据结构。不是拥有包含三个项目列表的字典,而是可以创建一个包含三元组的列表。

>>> files = {'key1': ['path1', 'path1', 'path2', 'path1', 'path2'], 
             'key2': ['f', 'f', 'f', 'f', 'f'], 
             'key_file': ['file1', 'file1', 'file2', 'file1', 'file2']}
>>> files2 = set(zip(files["key1"], files["key2"], files["key_file"]))
>>> print files2
set([('path2', 'f', 'file2'), ('path1', 'f', 'file1')])

或者如果你想让它更像字典,你可以这样做,然后:

>>> files3 = [{"key1": k1, "key2": k2, "key_file": kf} for k1, k2, kf in files2]
>>> print files3
[{'key2': 'f', 'key1': 'path2', 'key_file': 'file2'}, 
 {'key2': 'f', 'key1': 'path1', 'key_file': 'file1'}]

请注意,顶级列表中三元组的顺序可能不同,但属于一起的项目仍然在包含的元组或词典中。

答案 4 :(得分:0)

这是我的实施:

In [1]: mydict = {'key1': ['path1', 'path1', 'path2', 'path1', 'path2'], 'key2': ['f', 'f', 'f', 'f', 'f'], 'key_file': ['file1', 'file1', 'file2', 'file1', 'file2']}

In [2]: { k: sorted(list(set(v))) for (k,v) in mydict.iteritems() }
Out[2]: {'key1': ['path1', 'path2'], 'key2': ['f'], 'key_file': ['file1', 'file2']}

<强>测试

In [6]: mydict
Out[6]:
{'key1': ['path1', 'path1', 'path2', 'path1', 'path2'],
 'key2': ['f', 'f', 'f', 'f', 'f'],
 'key_file': ['file1', 'file1', 'file2', 'file1', 'file2']}

In [7]: uniq = { k: sorted(list(set(v))) for (k,v) in mydict.iteritems() }

In [8]: for key in uniq:
   ...:     print 'KEY    :', key
   ...:     print 'VALUE  :', uniq[key]
   ...:     print '-------------------'
   ...: 
KEY    : key2
VALUE  : ['f']
-------------------
KEY    : key1
VALUE  : ['path1', 'path2']
-------------------
KEY    : key_file
VALUE  : ['file1', 'file2']
-------------------