2015-01-15 80 views
0

一个关键的重复值我有这样一本字典:的Python删除字典

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

我想删除其他键UND在“KEY_FILE”所有重复的值和它们的其他价值('键1 '和'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'一样。其实在现实中有更多的关键,但这是我最小的例子。这是我的问题。我发现了几个解决方案来删除每个副本。

EDIT2:

也许我有点困惑。

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

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

我希望这解释得更好。

+1

'[ 'F', 'F', 'F', 'F', 'F']'变成' ['f','f']'? – thefourtheye 2015-01-15 15:15:15

+0

要删除重复请参阅此问题:http://stackoverflow.com/questions/480214/how-do-you-remove-duplicates-from-a-list-in-python-whilst-preserving-order 除此之外,它只是一个通过字典的项目循环:) – Wolph 2015-01-15 15:16:55

+1

@thefourtheye是的,看看编辑的文本。 – Keynaan 2015-01-15 15:29:24

回答

2

天真的方法:遍历键添加到新字典的每个值:

>>> 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')] 
+0

非常感谢。这看起来像我正在寻找的解决方案。 – Keynaan 2015-01-15 15:45:15

+1

如果使用相同的'key_file',但具有不同的'key1'或'key2'的三元组条目,该怎么办? – 2015-01-15 15:54:30

+0

@tobias_k没有想过这种情况。不知道它可能发生。我已要求OP澄清。 – fredtantini 2015-01-15 16:05:04

1

OrderedDict是最好的,因为它保留秩序

你可以把它添加到一组,然后使它成为一个列表

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

为什么要downvotes bro?我的回答很差吗? – 2015-01-15 15:20:07

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'])]) 
+0

谢谢你的快速回答。我上面编辑了我的问题。我忘了提及,我想保留每个键的长度。 – Keynaan 2015-01-15 15:37:56

+0

@Keynaan欢迎,所以你的意思是说,你想所有的价值观与长期价值相同的长度? – Kasramvd 2015-01-15 15:39:55

+0

在这种情况下,我需要每个键的2个值。 @fretantini有答案,但也谢谢你。 – Keynaan 2015-01-15 15:44:43

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'}] 

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

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'] 
-------------------