0

I've just recently started learning programming in python as a beginner. I was wondering: are keys in dictionary also treated as variables?

students = {"Jake": 12, "Rachel":12, "Ross":15}

the code contains the student names and their age. For example: Is "Jake" a variable that contains the value 12? or is it treated as a variable?

  • 2
    No, keys are not variables. – juanpa.arrivillaga May 06 '18 at 16:55
  • Here is one of the best [starting points](https://nedbatchelder.com/text/names1.html) for names and values in Python. – dawg May 06 '18 at 17:00
  • https://docs.python.org/3/library/stdtypes.html#mapping-types-dict – Stephen Rauch May 06 '18 at 17:01
  • It is a variable in a broader sense of the word. In a module or a class object, for instance, variables are held in dictionaries. When you reference the variable, python looks it up in the namespace `__dict__`. You can reassign `"jake"` in the dict, so its variable-like in that case too. The thing you can't do is use it as a variable on the dictionary, e.g., `students.Jake`. You could even make that work if you inherit from `dict` can create your own magic methods to use it. – tdelaney May 06 '18 at 17:09

3 Answers3

1

While you can use a named value (or what you might think of as a 'variable') to construct a dictionary:

>>> x=22
>>> di={x:x}
>>> di
{22: 22}

You can also demonstrate that the value of the named value (if that value is immutable) is used at the time of construction and not dynamic:

>>> x=5
>>> di
{22: 22}

The keys of a dict must be hashable (ie, unchanging; immutable) which would preclude the use of a list, set, or other named value that can change:

>>> changeable_list=[22]
>>> di={changeable_list:changeable_list}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

But the value of a dict can be dynamic and mutable:

>>> di={tuple(changeable_list):changeable_list}
>>> di
{(22,): [22]}

And that list can be modified:

>>> changeable_list.append(44)
>>> changeable_list
[22, 44]
>>> di
{(22,): [22, 44]}

Notice how the value of the dict changes as the list changes because they are the same object.

dawg
  • 98,345
  • 23
  • 131
  • 206
  • But `foo.x=22` does the same thing. And if you do `x=[22]` you do assign a dynamic object. "dynamic" is a property of the object assigned, not the assignment. – tdelaney May 06 '18 at 17:14
  • @tdelaney: I don't follow your comment. Can you explain? – dawg May 06 '18 at 17:19
  • You assigned an integer to `x` and later assigned a different integer to `x` and showed that the dict value didn't change. But variables work exactly the same way. `x=22;y=x;x=5`. I just don't see how that makes dict keys "not a variable". The only difference I see is that dicts hold keys that are not syntactically correct python and so you don't get the convenience of python's automatic resolution rules. But you can do that yourself. Variables (except function locals) reside in dictionaries so aren't all dictionary items variables? – tdelaney May 06 '18 at 17:24
  • The question was about the keys of a dict. You cannot change the key dynamically by any means in Python. The demo was to show that the use of `di={x:[whatever]}` takes the *current value* of x and uses that for the key during the dict construction. After the dict is constructed, there is no longer any connection to `x` (well -- unless they both refer to an [interned](https://stackoverflow.com/a/20863199/298607) value, but that is not in the scope of this question I think) – dawg May 06 '18 at 17:33
  • OP literally asked: _Is "Jake" a variable that contains the value 12?_ – tdelaney May 06 '18 at 17:37
  • I saw nothing in the question suggesting he wanted to change "Jake" to, say, "Foo". – tdelaney May 06 '18 at 17:39
  • Help me understand what you are suggesting I change? I don't mean to be thick, but I am not understanding. I am trying to show that the value of `x` just as the return value of a function or any other named 'variable' is referenced for keys at the time of contraction of the dict and not later. If it is a key, it must reduce immediately to an immutable value; if it is a dict value, it does not. That is what I was trying to say and show... :-) – dawg May 06 '18 at 18:22
  • I think you and I have read the question differently. A dict is a namespace and you can reference or reassign values just like with python variables. I think OP is just trying to figure out the difference between `Jake` as a variable and `Jake` as a key in a dictionary. They are about the same. I can `print(Jake)` or `print(students["Jake"])`. I can `Jake = 42` or `students[Jake"] = 42`. They are just about the same. Since variable namespaces in python are usually dicts, its not too surprising! – tdelaney May 06 '18 at 18:30
0

As has been said, No, the keys of a dictionary are not variables. However, variables can sometimes key thought of as keys:

students = {"Jake": 12, "Rachel":12, "Ross":15}

class Students:
    pass

s = Students()
s.Jake = 12
print(s.Jake, students['Jake'])

print(getattr(s, 'Jake'))

Output:

12 12
12

There is no syntax that I'm aware of that would allow you to access the value 12 from students in this form: students.Jake

However, modify the above code:

class Students:
    def __getitem__(self, key):
        return getattr(self, key)

... # as before
print(getattr(s, 'Jake'), s['Jake'])

Output:

12 12

Now students has an operator[] a little like a dictionary (Other operators might also be necessary.)

So, an object can become like a dictionary because they have an underlying dictionary to make them work as objects.

quamrana
  • 37,849
  • 12
  • 53
  • 71
  • It depends on what you mean by "variable". `dict` can hold many keys that would not be allowed syntactically in the python language. You have to address them as `foo["bar"]` instead of `foo.bar` but that's really the only difference. – tdelaney May 06 '18 at 17:11
0

TL;DR - it depends on what you mean by a "variable". dicts act like python namespaces but allow more types of variable names.

Python objects have no inherent name. They can be referenced by one or more other objects and when their reference count goes to zero, they are deleted. When you assign an object to a variable, some data structure adds a reference to the the object and associates that object with the name. That data structure is the variable's namespace (that is, the context where the variable name is valid). And for most objects, that data structure is a dict.

Lets look at two examples:

class Students:
    pass

student_obj = Students()

and

student_dct = {}

I could treat Jake as a a variable

>>> student_obj.Jake = 12
>>> student_obj.Jake
12
>>> student_obj.__dict__
{'Jake': 12}

Or add it to the dict

>>> student_dct["Jake"] = 12
>>> student_dct["Jake"]
12
>>> student_dct
{'Jake': 12}

That's really close to the first example! The advantage to a variable is that it is parsed by python and python does the lookup for you. Python turns student_obj.Jake into student_obj.__getattribute__("Jake"). For normal class objects, python will check the object __dict__ for the name then fall back to containing namespaces. Classes that use __slots__ or are implemented in C follow different rules.

But variable assignment is a disadvantage if you want to use names that don't fit python's sytax rules.

>>> student_obj.Jim Bob = 12
  File "<stdin>", line 1
    student_obj.Jim Bob = 12
                      ^
SyntaxError: invalid syntax

Here, you want "Jim Bob" to be a variable but it can't be used directly as a variable because it breaks python. So, you put it into a dict

>>> student_dct["Jim Bob"] = 12

So, dictionary items are "variables" (the value can be referenced and reassigned) but are not "python variables" because python doesn't implement the lookup for you.

tdelaney
  • 73,364
  • 6
  • 83
  • 116