![]() |
assign a value to a dict change all the values - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Data Science (https://python-forum.io/forum-44.html) +--- Thread: assign a value to a dict change all the values (/thread-12912.html) Pages:
1
2
|
assign a value to a dict change all the values - aster - Sep-18-2018 hello, i am really getting mad with these few lines of code from random import randint header = ["test", "1", "2", "12", "GG", "NG"] lis = ["alpha", "beta", "gamma"] list_p = list() dict_p = dict.fromkeys(header) def random(): for item in lis: dict_p["test"] = item for key in list(dict_p.keys())[1:]: dict_p[key] = randint(1,600)/100.0 list_p.append(dict_p) return list_p print(random())i know from here that Changing One dict value changes all values in a list and even if i feel completely dumb i am not able to apply these answers to my case could you explain what i am doing wrong? ![]() RE: assign a value to a dict change all the values - Larz60+ - Sep-18-2018 could you explain what you think is wrong, what to expect the results should be, any error messages, etc, In other words something to go on. RE: assign a value to a dict change all the values - Windspar - Sep-18-2018 List are reference variables. They are always pass as reference. When you assign one list to all variables. It all point to the same list. Examples import numpy as np td =[np.Inf, 2, 3] a = {} for k in range(10): a[k] = td # point to one list a[0][0] = 1 td[1] = 10 for i in a.items(): print(i) b = {} for k in range(10): b[k] = td[:] # shallow copy b[0][0] = 2 td[1] = 0 print() for i in b.items(): print(i) a = [1, 2, 3] b = a c = a[:] # shallow copy print(a) print(b) print(c) print() a[1] = 6 b[0] = 5 c[2] = 7 print(a) print(b) print(c) RE: assign a value to a dict change all the values - aster - Sep-18-2018 Windspar thank you for your second example i didn t know about shallow copy Anyway i think that my problem isn t caused by the absence of a shallow copy Posting that stackexchange i brought you outside the road sorry As Larz60+ suggested this is my aim: In my code i am creating a dict with random numbers (dict_p) then i would like to add (append) this dict to a list (list_p) This is my output [{'test': 'gamma', '12': 3.89, 'NG': 0.06, '1': 2.82, '2': 4.31, 'GG': 0.95}, {'test': 'gamma', '12': 3.89, 'NG': 0.06, '1': 2.82, '2': 4.31, 'GG': 0.95}, {'test': 'gamma', '12': 3.89, 'NG': 0.06, '1': 2.82, '2': 4.31, 'GG': 0.95}]It shouldn t be all the same. For some reason that i don t understand the list is filled always with the last appended dict I would like that is was filled with different random generated dict RE: assign a value to a dict change all the values - ichabod801 - Sep-19-2018 Appending the variable for the dict just appends a pointer to where the dict is stored (the reference Windspar is talking about). The list items are all pointing to the same place, where the current value of the dict is stored. That's why you are seeing the last version of the dict repeated, because that is what is stored when you display it. If you want to save the current state to the list, change the append to list_p.append(dict_p.copy()) . That will create the shallow copy. Note that this won't work in all cases. Sometimes you need a deep copy.
RE: assign a value to a dict change all the values - aster - Sep-19-2018 thanks ichabod801 now almost everything is perfectly clear :) stupidly i thought that the reference you were talking about was referred to the list and not to the dict, now i understand it was a general explanation about how python works i re adapted the example of @Windspar to my case a = {'a':1,'b':2,'c':3} b = a c = a.copy() # shallow copy print(a) print(b) print(c) print() a['a'] = 6 b['b'] = 5 c['c'] = 7 print(a) print(b) print(c)now i am only confused by all these term that for me are completely news: copy, shallow copy and deep copy i guess that the pro of the shallow copy is that the code is faster and one cons could be that it bring newby like me to this error :P i have a doubt, from wikipedia says under the voice shallow copy: The referenced objects are thus shared, so if one of these objects is modified (from A or B), the change is visible in the other. Why in my case i didn't need a deep copy? and how it is possible that a shallow copy worked? is there any difference between a shallow copy and a "reference-copy"? RE: assign a value to a dict change all the values - ichabod801 - Sep-20-2018 The list is a reference too, just like the dictionary. A shallow copy of the list gives you all the items in the list. But some of those items can be references too. A shallow copy will just give you those references. >>> x = [1, 2, 3] >>> y = [x, 4, 5] >>> y [[1, 2, 3], 4, 5] >>> z = y[:] # shallow copy >>> y[1] = 6 >>> y [[1, 2, 3], 6, 5] >>> z [[1, 2, 3], 4, 5] # integers that are values don't have changes affect the shallow copy >>> x[1] = 7 >>> z [[1, 7, 3], 4, 5] # lists that are references do have changes affect the shallow copyA deep copy would make an independent copy of everything in the list. RE: assign a value to a dict change all the values - aster - Sep-20-2018 Wowwwwww before i wouldn t never thought that it had such this behaviour! Now it is more clear, i also feel a "fear" (for unexpected behaviour) to use everything which isn t a deep copy ? Edit: Tomorrow i will try your example with tuples, i am really curios about it RE: assign a value to a dict change all the values - ichabod801 - Sep-21-2018 You can't assign to a tuple index, so it won't work. This is an important point in Python. Mutables, like lists, dictionaries, and sets, display the behavior you see above. Immutables, like numbers, strings, and tuples, do not. RE: assign a value to a dict change all the values - aster - Sep-21-2018 (Sep-21-2018, 02:43 AM)ichabod801 Wrote: You can't assign to a tuple index, so it won't work. This is an important point in Python. Mutables, like lists, dictionaries, and sets, display the behavior you see above. Immutables, like numbers, strings, and tuples, do not. yes i know, what i wanted to check is if i can change the item pointed by a reference from copy import deepcopy x = [1, 2, 3] y = (x, 4, 5) print(y) z = deepcopy(y) x[1] = 7 print(y) print(z)and i can, please tell me if i am wrong: i can change it because the reference of 'x' inside y is always the same ![]() but so which is the difference between a normal copy and a shallow copy? i am almost sure that i understood correctly the difference between a copy and a deep copy, the last one is completely a new object while the first is a reference to the original object |