2012-03-21 67 views
5

我正試圖找到一種在Maya中使用Python字典刪除重複着色器的方法。從字典中提取重複值

下面是我在做什麼:

我希望把所有瑪雅着色成字典作爲鑰匙,並把相應的紋理文件作爲值。然後我希望腳本能夠通過字典運行,並找到任何共享相同值的鍵並將它們填入數組或另一個字典中。

這基本上就是我現在所擁有的:

shaders_dict = {'a': somePath, 'b': somePath, 
       'c': differentPath, 'd': differentPath} 

duplicate_shaders_dict = {}` 

如何我現在可以通過字典運行編譯另一個字典,看起來是這樣的:

duplicate_shaders_dict = {'b':somePath, 'd':differentPath } 

而棘手的部分是因爲有重複我想腳本skip the original key,所以它不會被塞滿重複着色器字典。

+3

我假設你的意思是'a'在你的例子中是「原始鍵」。我想指出的是,字典沒有下訂單,「原始鑰匙」只能意味着「第一次遇到」。 – freespace 2012-03-21 01:06:32

回答

3

一個簡單的解決方案是反轉字典。鑑於:

>>> d = {'a': 'somePath', 'b': 'somePath', 
... 'c': 'differentPath', 'd': 'differentPath'} 

可以扭轉這樣說:

>>> r = dict((v,k) for k,v in d.iteritems()) 

它給你:

>>> r 
{'differentPath': 'd', 'somePath': 'b'} 

如果你扭轉,你有原來的字典,重複刪除:

>>> d = dict((v,k) for k,v in r.iteritems()) 
>>> d 
{'b': 'somePath', 'd': 'differentPath'} 
+0

和哪裏是與重複值的字典? – juliomalegria 2012-03-21 01:02:45

+0

呵呵,錯過了那部分。這從問題的「我有」部分開始,併產生「我想要的」部分,因此它可能是一個很好的開始。 – larsks 2012-03-21 01:06:00

+0

這是有道理的:但我不想擺脫重複,我需要把它們放入另一個變量,以便稍後我可以對它們採取行動,然後將它們從場景中刪除 – 2012-03-21 01:08:20

4

我會pr可以做這樣的事情。首先,逆詞典:

>>> from collections import defaultdict 
>>> 
>>> shaders_dict = {'a':'somePath', 'b':'somePath', 'c':'differentPath', 'd':'differentPath'} 
>>> 
>>> inverse_dict = defaultdict(list) 
>>> for k,v in shaders_dict.iteritems(): 
...  inverse_dict[v].append(k) 
... 
>>> inverse_dict 
defaultdict(<type 'list'>, {'differentPath': ['c', 'd'], 'somePath': ['a', 'b']}) 

這基本上是通過遍歷每個鍵,值對和附加的關鍵在於與價值相關聯的列表反轉字典。

然後拆分此:

>>> first_shaders_dict = {} 
>>> duplicate_shaders_dict = {} 
>>> for v, ks in inverse_dict.iteritems(): 
...  first, rest = ks[0], ks[1:] 
...  first_shaders_dict[first] = v 
...  for r in rest: 
...   duplicate_shaders_dict[r] = v 
... 
>>> first_shaders_dict 
{'a': 'somePath', 'c': 'differentPath'} 
>>> duplicate_shaders_dict 
{'b': 'somePath', 'd': 'differentPath'} 

嗯。這假定紋理文件是可散列的,所以可以作爲字典鍵。如果他們不是,那麼我必須解決這個問題。另外,因爲@freespace註釋在這裏沒有排序,如果你想要一個特定的順序,我們必須遍歷排序的鍵或類似的東西。

-

更新:我不喜歡上述多。較短的基於itertools的版本:

>>> import itertools 
>>> shaders_dict = {'a':'somePath', 'b':'somePath', 'c':'differentPath', 'd':'differentPath'} 
>>> keys = sorted(sorted(shaders_dict),key=shaders_dict.get) 
>>> by_val = [(v, list(ks)) for v, ks in itertools.groupby(keys, shaders_dict.get)] 
>>> first_dict = dict((ks[0],v) for v,ks in by_val) 
>>> duplicate_dict = dict((k,v) for v,ks in by_val for k in ks[1:]) 
>>> first_dict 
{'a': 'somePath', 'c': 'differentPath'} 
>>> duplicate_dict 
{'b': 'somePath', 'd': 'differentPath'} 
+0

這一個做到了!雖然這對我來說有點「魔力」。我將研究這個解決方案。 – 2012-03-21 01:17:12

+0

+1更新... – 2012-03-21 02:36:47