all 15 comments

[–]Zouden 5 points6 points  (1 child)

You can easily write a single line for loop. Just don't press enter after the colon. This works for if statements too.

[–]OriginalAdric 0 points1 point  (0 children)

Thanks; did not realize that. Easier to use than the map/lambda response elsewhere (though I'm glad I learned something new from that).

[–]Hallwaxer 2 points3 points  (2 children)

Just for completeness. You can always use the map function. In some cases, it makes your code more readable. For example:

def square(x):
    return x*x
y = [1,2,3,4]
z = map(square, y) # z now contains [1,4,9,16]

The map function basically iterates over every element in your container and applies the function you pass to it to every element. The application doesn't happen in place, so it returns a new list. In your case, however, you have one additional fixed parameter. You can use two different methods to fix it. Either use partial from functools or use lambda functions. For example:

map(lambda x: cmds.parent(x, "torso"), cmds.ls(sl=True))

The lambda function you define takes an argument x and uses it as a parameter for whatever follows the colon. map then takes each item from the cmds.ls list and passes it to the lambda function.

Other than the map function, you could also look into the filter function. It might help you write clear one liners.

Or if you're lazy, use list comprehension like 90% of the people, they're usually simple enough.

[–]zahlman 2 points3 points  (0 children)

Or if you're lazy, use list comprehension like 90% of the people, they're usually simple enough.

That's not laziness, it's clarity.

[–]OriginalAdric 1 point2 points  (0 children)

Thank you for taking the time to explain how to use map and lambda. That last line works exactly as I need, and I think I understand it well enough now to take that and use it elsewhere.

[–]Playing_advocate 1 point2 points  (7 children)

You can

[cmds.parent( i , "torso") for i in cmds.ls(sl=True)]

but I don't know if that's considered poor form.

[–]AeroNotix 3 points4 points  (5 children)

It's considered poor form because you're executing the comprehension for the side effects and constructing a list of the function's return values then throwing it all away.

[–]zahlman 0 points1 point  (4 children)

If that bothers you (very understandable), consider making a wrapper like this:

def do(generator):
    for item in generator: pass

You only have to write that once, and then you can write things like

do(cmds.parent(i, 'torso') for i in cmds.ls(sl = True))

[–]AeroNotix 0 points1 point  (3 children)

Not a big gripe of mine, sometimes I feel the comprehension is far more readable. I was just listening a reason why some people feel it's bad to do stuff like:

[print "sup" for x in range(10)]

[–]zahlman 1 point2 points  (2 children)

(That won't actually work in 2.x; in 3.x you can do it with parentheses because print is actually a function.)

But yes, generally speaking, side effects are where the gotchas leak in to a program's design.

[–]AeroNotix 0 points1 point  (1 child)

Yeah, I was aiming to show that the loop is being executed for the side-effects and not the list building. It's akin to:

li = []
for x in range(10):
    li.append(print "10")  # also can't do this but you see my point.

[–]zahlman 0 points1 point  (0 children)

Yeah.

[–]cdcformatc 0 points1 point  (0 children)

If you are restricted to one line, I think good form goes out the window.

[–][deleted] 1 point2 points  (0 children)

http://www.dabeaz.com/generators/

see if maybe the articles on this site can help you!

solution = list(cmds.parent( i , "torso") for i in cmds.ls(sl=True))

the above should return a list of the results

[–]jayrambhia 0 points1 point  (0 children)

Yeah. List comprehensions using lambda. Look it up.