Skip to content Skip to sidebar Skip to footer

Python Nested Dictionary Comprehension In Static Class Scope: Variable Not Defined

I've got this code: class Chars: char_to_number = { 'a': ['1'], 'b': ['2'], 'c': ['3', '6'], 'd': ['4', '5'], } number_to_char = {

Solution 1:

The essence of the problem is not the nesting. It's the fact that there's a flaw in the scope in comprehensions used within classes. To understand why this looks like a flaw, take the code from the original question by @gal-ben-david and put it in a function (print statement and function call added to generate output and confirm that this code works, at least in Python 3.6.6):

def Chars():
    char_to_number = {
        'a': ['1'],
        'b': ['2'],
        'c': ['3', '6'],
        'd': ['4', '5'],
    }
    number_to_char = {
        number: charforchar in char_to_number
        for number in char_to_number[char]
    }
    print(number_to_char)

To understand why nesting is not the problem, take a look at the example in the explanation for this "limitation", in the section on the execution model of the Python language reference:

class A:
    a = 42
    b = list(a + i for i in range(10))

The variable "a" is not in the scope of the comprehension if these two lines appear in a class, but it would be in a function or module. I call that a bug. To formalize the limitation a bit: when a comprehension is used in a class, only the outermost iterator in the for loop(s) is accessible inside the comprehension, but no other variables from outside the comprehension are accessible.

Comprehensions are presented as being equivalent to for loops, but obviously they aren't. While the nature of this flaw is being debated (bug or not bug), I've submitted a ticket to the developers about the documentation of comprehensions, which really should mention this problem prominently.

I don't have enough points to comment on @armatita's response, but note that it's a workaround and not equivalent to what the original code is trying to do, because it makes char_to_number and number_to_char attributes of each class instance and not of the class itself. I landed on this page because I was trying to assign class attributes.

Solution 2:

I believe it's because there's no permanent definition of your objects as you have in a global scope. If you make your variables permanent in the scope of your class the problem should be solved:

class Chars:
    def __init__(self):
        self.char_to_number = {
            'a': ['1'],
            'b': ['2'],
            'c': ['3', '6'],
            'd': ['4', '5'],
        }

        self.number_to_char = {
            number: charforcharinself.char_to_number
            for number inself.char_to_number[char]
        }

c = Chars()

Post a Comment for "Python Nested Dictionary Comprehension In Static Class Scope: Variable Not Defined"