在Python中同时迭代三个列表?
这个问题可能有点复杂,因为很多人可能不太了解我正在使用的软件:Autodesk Maya 2011。我想通过写一个脚本来自动化一个繁琐且缓慢的过程(绑定:让3D角色能够移动),以此来加快这个过程。
我会尽量把情况解释清楚。
我有一个脚本,它会拿一个对象,遍历这个对象的所有子对象,把它们存储在一个列表里,然后把最初的对象放到列表的最后面,接着把列表反转,因为顺序是错的,最后再把最初的对象放到最前面。
问题是:我有三个不同的列表,它们都是同一种类型的对象,但名字不同,实际上是不同的对象。我的目标是通过生成叫做“blendcolors”的节点把它们连接在一起。但是如果我为列表A中的每个对象生成一个循环,那么我还需要循环把它们连接到其他列表中的对象,这让我很困惑。
这是我的代码,经过一些修改后,现在在实际的循环部分变得更加不完整了。
import maya.cmds as cmds
def crBC(IKJoint, FKJoint, bindJoint, xQuan, switch):
# gets children joints of the selected joint
chHipIK = cmds.listRelatives(IKJoint, ad = True, type = 'joint')
chHipFK = cmds.listRelatives(FKJoint, ad = True, type = 'joint')
chHipBind = cmds.listRelatives(bindJoint, ad = True, type = 'joint')
# list is built backwards, this reverses the list
chHipIK.reverse()
chHipFK.reverse()
chHipBind.reverse()
# appends the initial joint to the list
chHipIK.append(IKJoint)
chHipFK.append(FKJoint)
chHipBind.append(bindJoint)
# puts the last joint at the start of the list because the initial joint
# was added to the end
chHipIK.insert(0, chHipIK.pop())
chHipFK.insert(0, chHipFK.pop())
chHipBind.insert(0, chHipBind.pop())
# pops off the remaining joints in the list the user does not wish to be blended
chHipBind[xQuan:] = []
chHipIK[xQuan:] = []
chHipFK[xQuan:] = []
# goes through the bind joints, makes a blend colors for each one, connects
# the switch to the blender
for a in chHipBind
rotBC = cmds.shadingNode('blendColors', asUtility = True, n = a + 'rotate_BC')
tranBC = cmds.shadingNode('blendColors', asUtility = True, n = a + 'tran_BC')
scaleBC = cmds.shadingNode('blendColors', asUtility = True, n = a + 'scale_BC')
cmds.connectAttr(switch + '.ikFkSwitch', rotBC + '.blender')
cmds.connectAttr(switch + '.ikFkSwitch', tranBC + '.blender')
cmds.connectAttr(switch + '.ikFkSwitch', scaleBC + '.blender')
# goes through the ik joints, connects to the blend colors
for b in chHipIK:
cmds.connectAttr(b + '.rotate', rotBC + '.color1')
cmds.connectAttr(b + '.translate', tranBC + '.color1')
cmds.connectAttr(b + '.scale', scaleBC + '.color1')
# connects FK joints to the blend colors
for c in chHipFK:
cmds.connectAttr(c + '.rotate', rotBC + '.color2')
cmds.connectAttr(c + '.translate', tranBC + '.color2')
cmds.connectAttr(c + '.scale', scaleBC + '.color2')
# connects blend colors to bind joints
cmds.connectAttr(rotBC + '.output', d + '.rotate')
cmds.connectAttr(tranBC + '.output', d + '.translate')
cmds.connectAttr(scaleBC + '.output', d + '.scale')
# executes function
crBC('L_hip_IK', 'L_hip_FK', 'L_hip_JNT', 6, 'L_legSwitch_CTRL')
5 个回答
1
为什么会有“三个不同的列表,都是同一种对象类型”?为什么不能把它们合成一个列表,让这三个对象正确匹配呢?
其实,使用一个简单的映射比三个并行的列表要好得多。
具体来说,你需要修正 chHipIK = cmds.listRelatives(IKJoint, ad = True, type = 'joint')
让它像这样工作。
chHipIK = [ { 'IK': ik } for ik in mds.listRelatives(IKJoint, ad = True, type = 'joint') ]
for i, fk in enumerate(cmds.listRelatives(FKJoint, ad = True, type = 'joint')):
chHipIK[i]['FK']= fk
for i, bind in enumerate(cmds.listRelatives(bindJoint, ad = True, type = 'joint')):
chHipIK[i]['FK']= bind
这样 chHipIK
就会变成一个包含所有三条信息的映射列表。
3
Python3 的答案:
for a, b, c in zip(lst1, lst2, lst3):
...
32
我不太明白这个问题,你是在寻找
import itertools
for a, b, c in itertools.izip(lst1, lst2, lst3):
...
吗?
izip
的作用是,它可以接收多个参数,并返回一个迭代器。这个迭代器会依次输出每个参数中的对应项(第一次运行时输出第一个参数的元组,第二次运行时输出第二个参数的元组,依此类推)。