Why can't I use a dictionary named `dict` before assigning to it?

Question:

I have multiple files that I need to load so I’m using a dict to shorten things. When I run I get a

TypeError: 'type' object is not subscriptable 

Error. How can I get this to work?

m1 = pygame.image.load(dict[1])
m2 = pygame.image.load(dict[2])
m3 = pygame.image.load(dict[3])
dict = {1: "walk1.png", 2: "walk2.png", 3: "walk3.png"}
playerxy = (375,130)
window.blit(m1, (playerxy))
Asked By: Chanヨネ

||

Answers:

Normally Python throws NameError if the variable is not defined:

>>> d[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'd' is not defined

However, you’ve managed to stumble upon a name that already exists in Python.

Because dict is the name of a built-in type in Python you are seeing what appears to be a strange error message, but in reality it is not.

The type of dict is a type. All types are objects in Python. Thus you are actually trying to index into the type object. This is why the error message says that the “‘type’ object is not subscriptable.”

>>> type(dict)
<type 'type'>
>>> dict[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'type' object is not subscriptable

Note that you can blindly assign to the dict name, but you really don’t want to do that. It’s just going to cause you problems later.

>>> dict = {1:'a'}
>>> type(dict)
<class 'dict'>
>>> dict[1]
'a'

The true source of the problem is that you must assign variables prior to trying to use them. If you simply reorder the statements of your question, it will almost certainly work:

d = {1: "walk1.png", 2: "walk2.png", 3: "walk3.png"}
m1 = pygame.image.load(d[1])
m2 = pygame.image.load(d[2])
m3 = pygame.image.load(d[3])
playerxy = (375,130)
window.blit(m1, (playerxy))
Answered By: b4hand

you should update to python >= 3.9
and everything will work well

Answered By: Elad Rubi

When I stumbled across this error, I had this function:

def trainByDistribution(xs: pd.DataFrame, ys: pd.DataFrame, step) -> tuple[float]:

My idea was to create a function that takes two pandas dataframes and an integer and would return a tuple of floating-pointing numbers.

Like other answers have stated, in Python everything is objects, even classes themselves. Classes are in turn blueprint objects that can be used to generate new objects, and consequently classes can be assigned to variables, passed as arguments and programmatically constructed with type() function.

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __str__(self):
        return str(name) + str(age)

This class is equivalent to this:

def __init__(self, name, age):
    self.age = age
    self.name = name
def  __str__(self):
     return str(name) + str(age)
Person = type("Person, ("object",), {"__init__": __init__,
            "__str__": __str__})

This error "object is not subscriptable" appears when you pass to a function an object that doesn’t support accessing values by indexing (doesn’t overload the [] operator). Since the type of all classes is <class "type">:

>>> type(Person)
<class "type">

then type object is not subscriptable means you pass class instead of an actual object. This could be more tricky though, in my function above I passed valid dataframes, and my error appeared because I attempted to annotate the return type as tuple[float], and while this syntax should be legal to my knowledge, the interpreter understood this expression as if I wanted to index the tuple class itself.

Conclusions

This error appears when:

  • you pass class instead of an actual object to a function argument;
  • you use the class name to index anything, including naming variables with class names.

You can take a look at this tutorial by mCoding to find out more about classes as objects.

For me I go the same error once I try to access model class attributes like if it was dictionary dimension['dimension_id'] though dimension type is
app.models.evaluation.DimensionsEvaluation object so I got the error

TypeError: 'DimensionsEvaluation' object is not subscriptable

to fix this I had to get the dictionary field from the model class using .__dict__ and access my attribute normally like above:

...
for dimension in evaluation_dimensions:
    print(f"n dimension_id: {dimension['dimension_id']}n") #TypeError: 'DimensionsEvaluation' object is not subscriptable


for dimension in evaluation_dimensions:
    dimension_dic = dimension.__dict__
    print(f"n dimension_id: {dimension_dic['dimension_id']}n") #dimension_id: 1
...
Answered By: DINA TAKLIT
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.