我对这个问题感到难过,无论我怎么解决它,它仍然给我相同的结果。
基本上,据说我有两组 - 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
答案 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!=B
和A
具有相同的短名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))