从字典中提取重复值

时间:2012-03-21 00:52:55

标签: python dictionary

我正在尝试使用Python Dictionaries找到一种在Maya中删除重复着色器的方法。

以下是我正在做的事情:

我想将所有maya着色器放入字典作为键,并将相应的纹理文件作为值。然后我希望脚本运行字典并找到共享相同值的任何键,并将它们填充到数组或另一个字典中。

这基本上就是我现在所拥有的:

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

duplicate_shaders_dict = {}`

我现在如何通过该字典来编译另一个看起来像这样的字典:

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

由于存在重复,因此我需要脚本skip the original key,因此它不会被填入复制着色器字典。

2 个答案:

答案 0 :(得分:4)

我可能会做这样的事情。首先,制作逆字典:

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

答案 1 :(得分: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'}