1
$\begingroup$

Learning Process question:

This produces a list (which is great!!)

a = [x.name for x in objects if not x.hide and not x.parent and x.name not in mdlParent and x.type not in ("MESH", "CAMERA", "LIGHT")]
a
['00000000DE66']
    
print(a)
['00000000DE66']

However, trying to just Print based on the comprehension I get Syntax errors or generator object returns.

    print((x.name) for x in objects if not x.hide and not x.parent and x.name not in mdlParent and x.type not in ("MESH", "CAMERA", "LIGHT"))
    <generator object <genexpr> at 0x000001F6F5BD7F48>
        
    (x.name for x in objects if not x.hide and not x.parent and x.name not in mdlParent and x.type not in ("MESH", "CAMERA", "LIGHT"))
    <generator object <genexpr> at 0x000001F6F5CA87C8>
        
    print(([x.name for x in objects if not x.hide and not x.parent and x.name not in mdlParent and x.type not in ("MESH", "CAMERA", "LIGHT")]))
    []
        
    print([x.name for x in objects if not x.hide and not x.parent and x.name not in mdlParent and x.type not in ("MESH", "CAMERA", "LIGHT"])
    File "<blender_console>", line 1
        
    print([x.name for x in objects if not x.hide and not x.parent and x.name not in mdlParent and x.type not in ("MESH", "CAMERA", "LIGHT"])
                                                                                                                                          ^
    SyntaxError: invalid syntax

a = (x for x.name in objects if not x.hide and not x.parent and x.name not in mdlParent and x.type not in ("MESH", "CAMERA", "LIGHT"))
a
<generator object <genexpr> at 0x000001F6F5CA87C8>

This is what I'm trying to produce through Comprehension:

for x in objects:
     if not x.hide and not x.parent and x.name not in mdlParent and x.type not in ("MESH", "CAMERA", "LIGHT"):
         print(x.name)

OutPut:         
00000000DE66

So I can smack myself in the side of the head instead of thumping my forehead on the desktop, what am I doing wrong in my comprehension build ups?

Do I have to remove the "and"s and put in separate "if" statements?

That doesn't work either

a = (x.name for x in objects if not x.hide if not x.parent  if x.name not in mdlParent if x.type not in ("MESH", "CAMERA", "LIGHT"))
a
<generator object <genexpr> at 0x000001F6F5CA87C8>

a = (x for x.name in objects if not x.hide if not x.parent  if x.name not in mdlParent if x.type not in ("MESH", "CAMERA", "LIGHT"))
a
<generator object <genexpr> at 0x000001F6F5BD7F48>
$\endgroup$
2
  • 2
    $\begingroup$ There’s mismatched brackets in this bit “ not in ("MESH", "CAMERA", "LIGHT"])” (spot the single square bracket). I don’t know it that’s your only problem - just what I spotted. $\endgroup$ Mar 17 at 21:38
  • $\begingroup$ Thanks Rich, Appreciated I'll re-examine the statement. I think my biggest hang up is knowing exactly where to use the brackets (), [] and {}. $\endgroup$
    – PteJack
    Mar 18 at 22:14
3
$\begingroup$

You assign a list comprehension to a variable:

a = [x.name for x in objects if not x.hide and not x.parent and x.name not in mdlParent and x.type not in ("MESH", "CAMERA", "LIGHT")]

and the variable prints correctly both when you invoke it in the terminal and when you pass it to the print statement. Why not then, replace the a in your print statement, with the expression that you assign to a? The result will be the same:

print([x.name for x in objects if not x.hide and not x.parent and x.name not in mdlParent and x.type not in ("MESH", "CAMERA", "LIGHT")])

However, you actually tried that and got an empty list as a result:

print(([x.name for x in objects if not x.hide and not x.parent and x.name not in mdlParent and x.type not in ("MESH", "CAMERA", "LIGHT")]))

Additional parentheses are irrelevant (and redundant), so it should work. I suspect something happened before you executed this line of code, so that it no longer produced the expected result. To confirm, just after executing this line, try to execute again the lines that work, that is

a = [x.name for x in objects if not x.hide and not x.parent and x.name not in mdlParent and x.type not in ("MESH", "CAMERA", "LIGHT")]
a

It's very important that you execute both of these lines, as executing only the second one wouldn't recalculate the result and only display the result that has been calculated during the previous state of the project.

If you still have problems, please upload your .blend file: Blend-exchange

Some explanation on the confusing stuff: a list comprehension has a form of [... for ...]. If you don't use square or curly brackets, then it's a generator expression, which is significantly different than comprehensions, because it's not evaluated in place but instead creates a generator object, which keeps its state so you can read from it one value at a time. So if you do (don't) [i for i in range(100000000000000000)] it will hang and eventually eat all memory. Meanwhile (i for i in range(100000000000000000)) creates an object not much heavier than the single line of code defining it.

For a generalized code:

for step_variable in an_iterable:
    if condition:
        print(step_variable)

In order to mimic it exactly with a oneliner, it is a common practice to do this:

print(*[step_variable for step_variable in an_iterable if condition], sep="\n")

In this case it doesn't matter [other than performance-wise] if you use a generator expression instead, because the asterisk operator * would consume it entirely. sep argument is set to the same as end argument (which defaults to "\n") to mimic multiple prints for each of the unpacked values by the asterisk operator *.

$\endgroup$
1
  • $\begingroup$ Thanks Markus, your detailed explanation is very much appreciated. As I said in the comment above, I think my biggest problem is the bracketing within the actual statement, where to use which type of bracket. $\endgroup$
    – PteJack
    Mar 18 at 22:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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