up vote 1 down vote favorite

I was looking at the following code in python:

for ob in [ob for ob in context.scene.objects if ob.is_visible()]:
    pass

Obviously, it's a for each loop, saying for each object in foo array. However, I'm having a bit of trouble reading the array. If it just had:

[for ob in context.scene.objects if ob.is_visible()]

that would make some sense, granted the use of different objects with the same name ob seems odd to me, but it looks readable enough, saying that the array consists of every element in that loop. However, the use of 'ob', before the for loop makes little sense, is there some syntax that isn't in what I've seen in the documentation?

Thank you

flag

4 Answers

up vote 1 down vote accepted

That is the syntax for list comprehension.

link|flag
So your saying that the first word is the operation it preforms on each object that it gets? And because there is nothing besides ob there, it will do nothing? – Leif Andersen Mar 22 at 17:04
It's an expression for the object that goes into the list being constructed. The expression is just ob, so there's no change made. – Andrew McGregor Mar 22 at 17:13
up vote 0 down vote

The first ob is an expression, take this simple example:

>>>> [ x**2 for x in range(10) if x%2 == 0 ]
[0, 4, 16, 36, 64]

Which reads, create a list from range(10), if x is even then square it. Discard any odd value of x.

link|flag
up vote 0 down vote

It's a list comprehension. You can read it as:

create a list with [some_new_value for the_current_value in source_list_of_values if matches_criteria]

Think of:

[n*2 for n in [1,2,3,4]]

This means, for every item, n, create an entry in a new list with a value of n*2. So, this will yield:

[2,4,6,8]

In your case since the value ob is not modified, it's just filtering the list based on ob.is_visible(). So you're getting a new list of all ob's that are visible.

link|flag
up vote 0 down vote

It might help you see what's going on to rewrite your example code into this equivalent code:

temp_list = [ob for ob in context.scene.objects if ob.is_visible()]
for ob in temp_list:
    pass
link|flag

Your Answer

get an OpenID
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.