For loop that iterates over two lists

195 views
Skip to first unread message

Chris Meyers

unread,
Sep 12, 2018, 2:55:38 PM9/12/18
to Python Programming for Autodesk Maya
Hello,

    My first post here. I hope it's not too basic for you guys. I've been scripting for a while teaching myself, so please forgive my ignorance. I've been poking around for information on this and haven't run into the right post.

I have two sets of objects. One a set of base meshes, 'leafGeo_SET' and one a set of target meshes, 'leafTgt_SET'.

I'd like to write a for loop that will create a blend shape on each object in the 'leafGeo_SET' with the same indexed object in the 'leafTgt_SET'. Each blendshape will have only one target.  Eventually, I intend to also set keys in the timeline on the weights which is why I store the blendshape result in the variable. First things first.

Here's where i am, and getting an error... "Too many values to unpack"

import maya.cmds as cmds

#assign target and geo sets to variable without unicode in string
cmds.select('leafTgt_SET')
TGT = cmds.ls(sl=True, o=True)
cmds.select('leafGeo_SET')
GEO = cmds.ls(sl=True, o=True)

for g,t in GEO,TGT:
    #create a blendshape deformer with the objects in the list without testing geo and asign the output to variable BS.
    BS = cmds.blendShape(g,t)

I suspect you folks will say I'm going about it in the wrong way!

Chris






Russell Pearsall

unread,
Sep 12, 2018, 3:41:55 PM9/12/18
to Python Programming for Autodesk Maya
You can use zip (as in zipper) to combine the lists as you want.

for g,t in zip(GEO,TGT):
Some_func(g, t)

Justin Israel

unread,
Sep 12, 2018, 3:55:58 PM9/12/18
to python_in...@googlegroups.com
Starting from basics, you can loop over one list and use a counter to index into the same location on the matching target list:

x = ["a1","b1","c1"]
y = ["a2","b2","c2"]

i = 0
for item in x:
    print item, y[i]
    i += 1

Python provides an automatic way to do this approach:

for i, item in enumerate(x):
    print item, y[i]

The zip() function can create pair-wise items from two lists:

for item1, item2 in zip(x, y):
    print item1, item2

In python2, that has the downsize of creating potentially large temporary lists in memory for you to iterate over. So there is a more efficient generator option for very large lists :

from itertools import izip

for item1, item2 in izip(x, y):
    print item1, item2

Note in python 3, the zip() function becomes the efficient generator like izip() in python 2.

Justin 

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/44587126-3879-4b44-90d1-13e15ec60c4b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Chris Meyers

unread,
Sep 12, 2018, 5:49:09 PM9/12/18
to Python Programming for Autodesk Maya
Thank you both for your replies. It will take me some time to actually understand this but at least I know where to start now.

Chris Meyers

unread,
Sep 13, 2018, 8:37:45 AM9/13/18
to Python Programming for Autodesk Maya
So there really wasn't much to understand, it just worked perfectly. Thanks again to both of you!

Chris Meyers

unread,
Sep 13, 2018, 10:31:19 AM9/13/18
to Python Programming for Autodesk Maya
Just to follow up for any others that might see this that are still learning the basics like me.....

I ran into an issue with my original code that I posted above. Sometimes just selecting the set with cmds.select() it returns a list out of order. A post on highend3d provided the answer.....instead use cmds.listConnections(). Here is the code that worked and consistently returned the list in the correct order along with the rest of my script for setting keyframes on the weights.

import maya.cmds as cmds
#create a list of the members of each set and assign to variables 
TGT = cmds.listConnections('leafTgt_SET' + '.dagSetMembers')
GEO = cmds.listConnections('leafGeo_SET' + '.dagSetMembers')

for t,g in zip(TGT,GEO):
    #create a blendshape deformer from objects in each list and assign the result to variable.
    BS = cmds.blendShape(t,g)
    #set timeslider to frame 100
    cmds.currentTime(100)
    #set the blendshape w to 1. 
    cmds.setAttr(BS[0] + '.' + t ,1)
    #set more keyframes......
    cmds.setKeyframe(BS[0] + '.' + t)
    cmds.currentTime(115)
    cmds.setAttr(BS[0] + '.' + t,0)
    cmds.setKeyframe(BS[0] + '.' + t)




Reply all
Reply to author
Forward
0 new messages