Am I using Dictionaries right?

kaleidxkaleidx Posts: 6Member
edited March 2018 in Programming

Perhaps I'm missing something right in front of my eyes but I'm a little confused. I'm making a character creator of sorts ... so I have 3 dictionaries.
1 to hold the choices the player is making
2 for the confirmed player stats
3 for the confirmed npc stats

So when the player clicks the button, I want to transfer all the Dic1 data to one of the other dictionaries to make a character.
My problem is, after I've copied 1 dictionary to another, any time I edit one of the 1st dictionaries values the one I'm not editing seems to change as well.

Sorry if that sounds a little confusing but I made a simplified test to confirm my suspicions.

var p = {age = "1"}
var s = {age = "2"}
var t = {age = "3"}

func _on_Button_pressed():
    p = t
    print(p)
    print(s)
    print(t)

func _on_Button2_pressed():
    t.age = "4"
    s = t
    print(p)
    print(s)
    print(t)

The first button works fine but when I press button 2, even though I did nothing to Dictionary P, it still prints 4. Am I doing something obviously wrong? Does "x.key" Go through every key in every dictionary? I don't know why "p" is changing when I press button2.


Tags :

Best Answers

  • TwistedTwiglegTwistedTwigleg Posts: 1,824
    Accepted Answer

    I think the problem is in how you are using and accessing your dictionaries. To the best of my knowledge, you cannot assign and access variables in a dictionary like you do a class (unless you are using Javascript, which I think allows dictionary access like that).

    Here is how I've always been told to use dictionaries (converting your simplified test):

    "For a dictionary, you have to define your keys and values" "in the following format: dict = {key:value}" var p = {"age":"1"} var s = {"age":"2"} var t = {"age":"3"} func _on_Button_pressed(): "I'm using local variables instead of reassigning (feel free to change if you want)" var local_p = t print(local_p["age"]) print(s["age"]) print(t["age"]) func _on_Button2_pressed(): t["age"] = "4" "I'm using local variables instead of reassigning (feel free to change if you want)" var local_s = t print(p["age"]) print(local_s["age"]) print(t["age"])

    Note: you can print the entire dictionary if you want, just remove ["age"] to print the entire dictionary.

  • SolarLuneSolarLune Posts: 37
    Accepted Answer

    Am I doing something obviously wrong? Does "x.key" Go through every key in every dictionary? I don't know why "p" is changing when I press button2.

    This is because dictionaries aren't a base type (like ints, floats, strings, or Vectors), and so are passed by reference, not by value. You're changing the original dictionary because pressing the first button points p to t's dictionary in memory.

    Basically, imagine that for base types, a variable holds the value itself. However, for anything else, the variable is a line to a box that contains the value. You can change the value in the box much in the same way, but the distinction is important because multiple variables can be tied to the same box and thereby refer to and change the same value.

    This would also be the case with other kinds of objects, like arrays or class instances. Here's a simple code example:

    #  Create a dictionary, and assign it to the variable dictA
    var dictA = {"Test": 1} 
    
    #  Create a dictionary, and assign it to the variable dictB
    var dictB = {"Test": 2}
    
    #  Assign the variable dictB the dictionary in dictA
    dictB = dictA
    print( dictB["Test"] )  # Prints 2
    

    See the Godot API page on references.

Answers

  • TwistedTwiglegTwistedTwigleg Posts: 1,824Admin
    Accepted Answer

    I think the problem is in how you are using and accessing your dictionaries. To the best of my knowledge, you cannot assign and access variables in a dictionary like you do a class (unless you are using Javascript, which I think allows dictionary access like that).

    Here is how I've always been told to use dictionaries (converting your simplified test):

    "For a dictionary, you have to define your keys and values" "in the following format: dict = {key:value}" var p = {"age":"1"} var s = {"age":"2"} var t = {"age":"3"} func _on_Button_pressed(): "I'm using local variables instead of reassigning (feel free to change if you want)" var local_p = t print(local_p["age"]) print(s["age"]) print(t["age"]) func _on_Button2_pressed(): t["age"] = "4" "I'm using local variables instead of reassigning (feel free to change if you want)" var local_s = t print(p["age"]) print(local_s["age"]) print(t["age"])

    Note: you can print the entire dictionary if you want, just remove ["age"] to print the entire dictionary.

  • SolarLuneSolarLune Posts: 37Member
    Accepted Answer

    Am I doing something obviously wrong? Does "x.key" Go through every key in every dictionary? I don't know why "p" is changing when I press button2.

    This is because dictionaries aren't a base type (like ints, floats, strings, or Vectors), and so are passed by reference, not by value. You're changing the original dictionary because pressing the first button points p to t's dictionary in memory.

    Basically, imagine that for base types, a variable holds the value itself. However, for anything else, the variable is a line to a box that contains the value. You can change the value in the box much in the same way, but the distinction is important because multiple variables can be tied to the same box and thereby refer to and change the same value.

    This would also be the case with other kinds of objects, like arrays or class instances. Here's a simple code example:

    #  Create a dictionary, and assign it to the variable dictA
    var dictA = {"Test": 1} 
    
    #  Create a dictionary, and assign it to the variable dictB
    var dictB = {"Test": 2}
    
    #  Assign the variable dictB the dictionary in dictA
    dictB = dictA
    print( dictB["Test"] )  # Prints 2
    

    See the Godot API page on references.

  • CalinouCalinou Posts: 322Admin Godot Developer
    edited March 2018

    @TwistedTwigleg said:
    I think the problem is in how you are using and accessing your dictionaries. To the best of my knowledge, you cannot assign and access variables in a dictionary like you do a class (unless you are using Javascript, which I think allows dictionary access like that).

    GDScript supports dot notation for accessing dictionaries, but only for constant values. This means that for example, person.age will be treated like person["age"], not person[age] (age being a variable in the second example).

  • TwistedTwiglegTwistedTwigleg Posts: 1,824Admin

    GDScript supports dot notation for accessing dictionaries, but only for constant values. This means that for example, person.age will be treated like person["age"], not person[age] (age being a variable in the second example)

    Oh, I didn't know that. Good to know!

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file