从字典中提取重复值

问题描述:

我正试图找到一种在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

一个简单的解决方案是反转字典。鉴于:

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

我会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