1

Consider this simple Python dictionary and I want to change all the values to 4:
d = {'a': 1, 'b': 2, 'c': 3}

I know the following works the intended way:

for key, value in d.items():
    d[key] = 4
print(d)  # output: {'a': 4, 'b': 4, 'c': 4}

However, this doesn't:

for key, value in d.items():
    value = 4
print(d)  # output: {'a': 1, 'b': 2, 'c': 3}

When I inspected outputs of built-in id function of d[key] and value, they were the same.

Could anyone explain why value = 4 didn't work?

Elis Byberi
  • 1,422
  • 1
  • 11
  • 20
kh_0828
  • 19
  • 1
  • 3
  • 1
    Because it's not supposed to work. It just rebinds the name `value` to the value `4`, but that doesn't have anything to do with the dictionary. – mkrieger1 Nov 22 '17 at 14:44
  • I now see why it didn't work. Thank you for pointing to another question. – kh_0828 Nov 22 '17 at 15:01

1 Answers1

-1

When you iterate using for key, value in d.items(), the key and value variables are effectively copies (not quite as simple, but sufficient for this explanation) of the keys and values that you're iterating over.

Changing them directly won't modify the dictionary itself. Running the following code:

d = {'a': 1, 'b': 2, 'c': 3}

for key, value in d.items():
    print id(value)
    print id(d[key])
    value = 4
    print id(value)
    print id(d[key])
    print(d)  # output: {'a': 1, 'b': 2, 'c': 3}

gives the following output:

10158424
10158424
10158352
10158424
{'a': 1, 'c': 3, 'b': 2}
10158376
10158376
10158352
10158376
{'a': 1, 'c': 3, 'b': 2}
10158400
10158400
10158352
10158400
{'a': 1, 'c': 3, 'b': 2}

As you can see, before modifying value, the IDs are the same. After modifying it, they now reference different values.

Your first example, changes the actual dictionary in the intended way, by referencing a specific entry using the key, and modifying it.

roelofs
  • 2,132
  • 20
  • 25
  • Then why `id(d[key]) == id(value)` returns `True` ? – kh_0828 Nov 22 '17 at 14:52
  • That's why I said it's not quite as simple :) I see the question has been flagged as a duplicate. The other questions/answers actually explain why your statement evaluates to `True`. I expect that if you perform the `id` check after changing `value` in your second example, it will no longer be the same. – roelofs Nov 22 '17 at 14:54
  • You're right. `id` check after changing `value` returned `False`. Thanks. – kh_0828 Nov 22 '17 at 15:05
  • Hah, was busy updating the answer as you commented. – roelofs Nov 22 '17 at 15:08