How to mention the the value of a key by mentioning the key?

Suppose I have two dictionaries with one…uhh… directing to indexes of the other dictionary?

dict1 = {
        1: [3, 'a'],
        2: [4, 'b'],
        3: [6, 'c'],
        4: [8, 'd']
        }
dict2 = {
        'one': dict1[1][1],
        'two': dict1[2][0],
        'three': dict1[3][1],
        'four': dict1[4][0]
        }   
a = 'three'

Then I make some changes to variable a.

b = dict2[a]
c = b + '...'

Now I want to change the content of dict1, by assigning the change variable b to dict2
But if I use

b = c

It just changes the value of dict2.
Is there something that I am missing, are there other methods that I can do this?
Thanks!

dict2 = {
----> 8         'one': dict1[1][2],
      9         'two': dict1[2][1],
     10         'three': dict1[1][2],

IndexError: list index out of range

maybe the indexing is wrong.
also, could you give an example of what do you want dict1 to be after the change?

Also, you’ll not be able to concatenate a sting and a list.

b = dict2[a]
c = b + '...'

You should use the direct way:

dict1[x][y] = z

BTW, you said:

Actually, that doesn’t seem like a “directing” way. Doing some_mutable_obj[x] will just “bring” the wanted value:

lst = [1,2,3]
a = lst[0] # a == 1
a = 99 
print(a, lst) # 99 [1,2,3] ; NOT 99 [99,2,3]

You would be able to make a directing, if the target value(dict1[x][y] etc.) would be a list(or any other mutable object, but it is not in your case) :

mut_obj1 = [1,2,3]
mut_obj2 = mut_obj1
mut_obj1[1] = 100 # mut_obj1 == mut_obj2 == [1,100,3]
mut_obj2[2] = 10_000 #mut_obj1 == mut_obj2 == [1,100,10000]

And, there is one more important point about your code(as @vainaixr has already mentioned above) - you have:

[...]
'one': dict1[1][2]
[...]
'three': dict1[1][2]

But, last index in dict[1] is 1, not 2. Because dict[1] = [3,"a"] and first index is always 0.

For dict1, you are definitely right. But for dict2?

1 Like

This is not a topic that I’ve even considered (this was a simple observation on my part, based on my limited knowledge and the code that I saw) and is a little too abstract for me. You seem to have a have a very good understand of this and I’ll follow this thread so that I can learn from it.

So I was making a map of a game where @ would represent the player. I make a dictionary that stores where the player could be.

map = {

    1: ['_' for _ in range(36)],
    2: ['|' + ' ' * 10 + '+' + ' ' * 16 + '|', ' ' * 6, '|'],
    3: ['| ', 'Bathroom', ' |' + ' ' * 16 + '|', ' ' * 6, '|'],  
    4: ['|' + '_' * 10 + '|' + ' ' * 3, 'Living Room', ' ' * 2 + '|' + ' ' * 6 + '|'],
    5: ['|' + ' ' * 10 + '|' + ' ' * 16 + '|', 'Garden', '|'],
    6: ['| ', 'Kitchen', '  |' + ' ' * 16 + '|' + ' ' * 6 + '|'],
    7: ['|' + ' ' * 10 + '|' + '_' * 5 + '+' + '_' * 10 + '|' + ' ' * 6 + '|'],
    8: ['|' + '_' * 13 + '+__', '+', '_' * 8, '+', '_|' + ' ' * 6 + '|'],  
    9: ['|' + ' ' * 14 + '|', ' ' * 3, '|', ' ' * 4, '|', ' ' * 3, '|', ' ' * 6, '|'], 
    10: ['|' + ' ' * 3, 'Bedroom', ' ' * 4 + '|' + '_' * 3 + '|' + '_' * 5, ' ' * 3, '_' * 7 + '|'], 
    11: ['|' + '_' * 14 + '|' + ' ' * 11 + '/']
        }
d = {
    'Garden': map[2][4]
    'Front Porch': map[8][2]
    }

Then I make a loop that checks where the players current location is on the map and implement @ on it and then print the map.

    b = 1
    while b < a + 1:
        print(''.join(map[b]))
        b = b + 1

I have edited the post. Thanks to all of you who corrected me! :smiley:

Hey, I didn’t want to patronise. And, I haven’t got a “great” understanding or knowledge. I meant that none of dict2’s items is a list.

You didn’t: please don’t take offense, I meant none :slightly_smiling_face:
All I meant was that you seemed to grasp what the OP was driving at, whereas I failed to do so; it was my bad, not yours.
You have some very good skills, I can see that, and I’m sure that you have a promising future as a coder.
Peace.

So, to my mind, at this point, b is being defined as a list and as such can’t be concatenated with a string and assigned to c.
That was what I thought, but if I’m wrong, I’m wrong, and I’ll learn from that.

Sorry, but dict2[a] = dict1[3][1] = 'c'

dict1 = {
        1: [3, 'a'],
        2: [4, 'b'],
        3: [6, 'c'],
        4: [8, 'd']
        }
dict2 = {
        'one': dict1[1][1],
        'two': dict1[2][0],
        'three': dict1[3][1],
        'four': dict1[4][0]
        }   
a = 'three'

I hope you guys could have peace, or carry the argument somewhere else. :smiley:

No worries on my part. I thought that the post by @sandraC showed some very good insight; I even ‘liked’ it. I also think that she’s putting herself down by saying:

because she shows the exact opposite, not only in this thread, but in others too.

I sincerely apologise if I’ve offended anyone.

1 Like

So… does anyone have some advice?

If I am not mistaken, is this what you were suggesting?

No, you haven’t, really. And, thanks for your nice words.

1 Like

What you are seeing here is referred to in other languages as “value types” vs. “reference types”. If you’re interested, it’s a little dense but the relevant details of how Python stores objects are described here: Python 3.10 Data Model - Objects, Values, and Types

In short, Python values can be either mutable (their value can change) or immutable (their value is always the same). Integers and string values are immutable - when you create a variable pointing to a string or integer, then change the value stored in the variable, behind the scenes Python creates a new value and changes the variable to point to the new value. You can observe this with the built-in “id” function:

>>> a = 1
>>> id(a)
4491692336
>>> b = a
>>> id(b)
4491692336
>>> b = b + 1
>>> id(b)
4491692368

You can see that initially, the variables a and b are pointing to the same value - there is one instance of the value 1 being stored by Python, and both variables share it. However, when you change the value of variable b by incrementing it, it does not also change the value for variable a - instead, Python makes a new value and points b to that, and leaves a pointing to the old value.

The same thing happens with your dictionaries. Initially, your example variable b does point to the same value in memory as dict1[3][1]! However, as soon as you execute this statmement:

c = b + '...'

Python creates a new value for the result, and points c to that value. When you then try to copy the variable back into the dictionary:

b = c

This points b to the new value that was created, while dict1[3][1] still points to the old value.

If you want to have multiple explicit references to the same value (several variables pointing to the same place) so that when when one variable changes, the other variables see the same new value, you will need to use a mutable container. Python’s list and dict are mutable containers, but you can also create a simple class to do the same thing:

>>> class Ref:
...   def __init__(self, value):
...     self.value = value
... 
>>> a = Ref(1)
>>> b = a
>>> c = b
>>> a.value
1
>>> c.value = 2
>>> a.value
2

You can picture it a little like this (not a very good diagram):

 var_a -\                                   
         ---\                               
             --\               
 var_b ----------> Ref.value  ------> value
             --/  
         ---/                               
 var_c -/  
1 Like

May I ask if there is there a way to use len() after I used Ref() on it?