1

I wondered why the following list comprehension failed (UnboundLocalError: local variable 'y_value' referenced before assignment). If I literally spell out the for loops in a triple nested for loop, I nicely get the results I want.

for y_value_group in collinear_y_values:
    all_y_values = []
    for y_value in y_value_group:
        for line_id in horizontal_lines[y_value]:
            for p in LINES[line_id].pts:
                all_y_values.append(p.y)
    print(all_y_values)
    all_y_values = [p.y for p in LINES[line_id].pts for line_id in horizontal_lines[y_value] for y_value in y_value_group]
    print(all_y_values)

gives the following output:

[-0.01447138307529966, 0.22089181280929138, 0.22089181280929138, 0.19409634248390767]
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-85-62411ee08ee6> in <module>
     24     print(all_y_values)
---> 25     all_y_values = [p.y for p in LINES[line_id].pts for line_id in horizontal_lines[y_value] for y_value in y_value_group]
     26     print(all_y_values)

<ipython-input-85-62411ee08ee6> in <listcomp>(.0)
     24     print(all_y_values)
---> 25     all_y_values = [p.y for p in LINES[line_id].pts for line_id in horizontal_lines[y_value] for y_value in y_value_group]
     26     print(all_y_values)

UnboundLocalError: local variable 'y_value' referenced before assignment
mr_T
  • 2,571
  • 3
  • 22
  • 39
  • List comprehension is as follows `[ 1st loop 2nd for loop 3rd for loop]` and used `all_y_values = [p.y for p in LINES[line_id].pts for line_id in horizontal_lines[**y_value**] for y_value in y_value_group]` in 2nd loop but `y_value` comes from 3rd for loop. – Ch3steR Apr 20 '20 at 16:29
  • This might help you understand better : https://stackoverflow.com/questions/3633140/nested-for-loops-using-list-comprehension https://www.geeksforgeeks.org/nested-list-comprehensions-in-python/ [`python docs about nested list comprehension`](https://docs.python.org/3/tutorial/datastructures.html#nested-list-comprehensions) – Ch3steR Apr 20 '20 at 16:31

1 Answers1

5

Somewhat confusingly, in list comprehension you should put the outer loop first:

>>> [x for x in y for y in np.random.random((2,2))]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'y' is not defined
>>> [x for y in np.random.random((2,2)) for x in y]
[0.5656047153549479, 0.19139220091114273, 0.10286775868807774, 0.3230695608882298]

So just change the order:

[
    p.y 
    for y_value in y_value_group
    for line_id in horizontal_lines[y_value]
    for p in LINES[line_id].pts
]
BlackBear
  • 22,411
  • 10
  • 48
  • 86
  • Thanks.. I've had it backwards for months then, almost surprised that I didn't stumble upon this problem earlier then. – mr_T Apr 20 '20 at 16:37