在提取重复项时遇到问题

时间:2014-03-10 12:10:24

标签: python duplicates maya

我对这个问题感到难过,无论我怎么解决它,它仍然给我相同的结果。

基本上,据说我有两组 - GrpA_null和GrpB_null,每组都有2个网格,并且命名完全相同,brick_geo和bars_geo - 结果:GrpA_null - > brick_geo,bars_geo

但由于某种原因,在下面的代码中,我认为是给我问题的代码,当它运行时,程序声明GrpA_null与GrpB_null具有相同的副本,可能它们引用了brick_geo和bars_geo。一旦代码运行,我的孩子geo后面有一个数值, - 结果:GrpA_null - > brick_geo0,bars_geo0,GrpB_null1 - > brick_geo,bars_geo1

所以,我试图修改代码,只要父(GrpA_null和GrpB_null)不同,它就不会'触碰'孩子。

有人可以建议我吗?

    def extractDuplicateBoxList(self, inputs):
    result = {}

    for i in range(0, len(inputs)):
        print '<<< i is : %s' %i
        for n in range(0, len(inputs)):
            print '<<< n is %s' %n
            if i != n:
                name = inputs[i].getShortName()
                # Result: brick_geo

                Lname = inputs[i].getLongName()
                # Result: |GrpA_null|concrete_geo

                if name == inputs[n].getShortName():
                    # If list already created as result.
                    if result.has_key(name):
                        # Make sure its not already in the list and add it.
                        alreadyAdded = False
                        for box in result[name]:
                            if box == inputs[i]:
                                alreadyAdded = True
                        if alreadyAdded == False:
                            result[name].append(inputs[i])
                    # Otherwise create a new list and add it.
                    else:
                        result[name] = []
                        result[name].append(inputs[i])

    return result

3 个答案:

答案 0 :(得分:1)

您可能需要了解一些事项。首先,缩进在Python中很重要。我不知道你的代码缩进是否符合预期,但你的函数代码应该比你的函数def进一步缩进。

其次,我觉得你的问题有点难以理解。但有几件事可以改善你的代码。

在collections模块中,有(或应该是)一个名为defaultdict的类型。此类型与dict类似,不同之处在于它具有您指定类型的默认值。因此,当您获得密钥时,defaultdict(int)将具有默认值0,即使密钥之前不存在。这允许执行计数器,例如查找重复项而不进行排序。

from collections import defaultdict

counter = defaultdict(int)

for item in items:
    counter[item] += 1

这让我想到另一点。 Python for循环实现for-each结构。您几乎不需要枚举您的项目然后访问它们。所以,而不是

for i in range(0,len(inputs)):

你想用

for input in inputs:

如果你真的需要枚举你的输入

for i,input in enumerate(inputs):

最后,您可以使用列表推导,字典理解或生成器表达式迭代和过滤可迭代对象。它们非常强大。见Create a dictionary with list comprehension in Python

尝试使用此代码,使用它。看看它是否适合你。

from collections import defaultdict

def extractDuplicateBoxList(self, inputs):
    counts = defaultdict(int)

    for input in inputs:
        counts[input.getShortName()] += 1
    dup_shns = set([k for k,v in counts.items() if v > 1])
    dups = [i for i in inputs if input.getShortName() in dup_shns]

    return dups

答案 1 :(得分:0)

我的观点与 bitsplit 的评论相同,他已经完成了。

基于这些评论和get字典方法的使用,我现在只是给你一个我认为与你的代码完全相同的代码:

from collections import defaultdict

def extract_Duplicate_BoxList(self, inputs):
    result = defaultdict()

    for i,A in enumerate(inputs):
        print '<<< i is : %s' %i
        name  = A.getShortName() # Result: brick_geo
        Lname = A.getLongName()  # Result: |GrpA_null|concrete_geo

        for n in (j for j,B in enumerate(inputs)
                  if j!=i and B.getShortName()==name):
            print '<<< n is %s' %n
            if A not in result.get(name,[])):
                result[name].append(A)

    return result

其次,正如 bitsplit 所说,我觉得你的问题不可理解。
您能否提供有关投入要素的更多信息? 你对GrpA_null和GrpB_null以及名称和网格的解释都不清楚。

编辑:
如果我的缩减/简化是正确的,检查它,我看到你基本上做的是比较A的{​​{1}}和B元素(与inputs)并记录如果A!=BA具有相同的短名result,则shortname字典A B shortname def extract_Duplicate_BoxList(inputs): result = defaultdict() for i,A in enumerate(inputs): print '<<< i is : %s' %i result[B.getShortName()].append(A) return result ; {br> > 我认为这段代码仍然可以简化为:

{{1}}

答案 2 :(得分:0)

如果我理解它,这可能就是你要找的东西,这似乎是在比较不同节点的子层次结构,看看它们是否具有相同的名称。

import maya.cmds as cmds

def child_nodes(node):
    ''' returns a set with the relative paths of all <node>'s children'''
    root = cmds.ls(node, l=True)[0]
    children = cmds.listRelatives(node, ad=True, f=True)
    return set( [k[len(root):] for k in children])

child_nodes('group1')
# Result: set([u'|pCube1|pCubeShape1', u'|pSphere1', u'|pSphere1|pSphereShape1', u'|pCube1']) # 

# note the returns are NOT valid maya paths, since i've removed the root <node>, 
# you'd need to add it back in to actually access a real shape here:

all_kids = child_nodes('group1')
real_children  = ['group1' + n for n in all_kids ] 

由于返回是集合,您可以测试它们是否相等,看看是否是另一个的子集或超集,看看它们有什么共同点,等等:

# compare children
child_nodes('group1') == child_nodes('group2')

#one is subset:
child_nodes('group1').issuperset(child_nodes('group2'))

迭代一堆节点很简单:

# collect all the child sets of a bunch of nodes:
kids =   dict ( (k, child_nodes(k)) for k in ls(*nodes))