list comprehension vs for loop, within class definition

Viewed 151

Considering the code below:

class Test:
    l = [1, 2, 3]
    foo = lambda x: x

    for x in l:
        print(foo(x))

   [print(foo(x)) for x in l]


if __name__ == '__main__':
    test = Test()

The output is the following:

1
2
3
... in <listcomp>
    [print(foo(x)) for x in l]
NameError: name 'foo' is not defined

I don't understand why isn't foo a visible function from within the list iteration. Probably something to do with scopes but I am looking for the right explanation, with documentation to support it if possible.

ps: I am not interested in alternative implementations for the sake of just fixing the code.

2 Answers

As suggested in the comments, this question seems to pretty much answer the issue and goes a long way to thoroughly explain it. There is however a small variation that can be solved following a similar approach. The resulting code is as follows:

class Test:
    l = [1, 2, 3]
    foo = lambda x: x

    (lambda foo=foo, l=l: [print(foo(x)) for x in l])()

You can also use map if your desired list comprehension is simple enough:

class Test:
    l = [1, 2, 3]
    foo = lambda x: x
    
    list(map(print, map(foo, l)))

Outputs

1
2
3
Related