2015-01-15 71 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'] 
-------------------