Reputation: 23
I declared a python dictionary with key and value as multiple array. Is it possible to append an array using the key and value index?
This is the way I initialized the python dictionary cvfoldacc
a = []
b = []
c = []
d = []
e = []
f = []
classifiers = [a,b,c,d,e,f]
cvfoldacc = dict.fromkeys(range(2,11), classifiers)
And the result of this initialization is as follows:
cvfoldacc>>
{2: [[], [], [], [], [], []],
3: [[], [], [], [], [], []],
4: [[], [], [], [], [], []],
5: [[], [], [], [], [], []],
6: [[], [], [], [], [], []],
7: [[], [], [], [], [], []],
8: [[], [], [], [], [], []],
9: [[], [], [], [], [], []],
10: [[], [], [], [], [], []]}
When I tried to append the first list of key(2) with the code cvfoldacc[2][0].append(8), I am getting the result as:
{2: [[8], [], [], [], [], []],
3: [[8], [], [], [], [], []],
4: [[8], [], [], [], [], []],
5: [[8], [], [], [], [], []],
6: [[8], [], [], [], [], []],
7: [[8], [], [], [], [], []],
8: [[8], [], [], [], [], []],
9: [[8], [], [], [], [], []],
10: [[8], [], [], [], [], []]}
But the expected answer should be this:
{2: [[8], [], [], [], [], []],
3: [[], [], [], [], [], []],
4: [[], [], [], [], [], []],
5: [[], [], [], [], [], []],
6: [[], [], [], [], [], []],
7: [[], [], [], [], [], []],
8: [[], [], [], [], [], []],
9: [[], [], [], [], [], []],
10: [[], [], [], [], [], []]}
Upvotes: 0
Views: 61
Reputation: 6590
You need to create new list
s for values of each key
like,
>>> a = []
>>> b = []
>>> c = []
>>> d = []
>>> e = []
>>> f = []
>>> classifiers = [a,b,c,d,e,f]
>>>
>>> d = {k:[x[:] for x in classifiers] for k in range(2,11)} # note i am creating a copy using the `list[:]` notation.
# either the comprehension or `k: copy.deepcopy(classifiers)` is fine
>>> d
{2: [[], [], [], [], [], []], 3: [[], [], [], [], [], []], 4: [[], [], [], [], [], []], 5: [[], [], [], [], [], []], 6: [[], [], [], [], [], []], 7: [[], [], [], [], [], []], 8: [[], [], [], [], [], []], 9: [[], [], [], [], [], []], 10: [[], [], [], [], [], []]}
>>> d[2][0].append(1)
>>> d
{2: [[1], [], [], [], [], []], 3: [[], [], [], [], [], []], 4: [[], [], [], [], [], []], 5: [[], [], [], [], [], []], 6: [[], [], [], [], [], []], 7: [[], [], [], [], [], []], 8: [[], [], [], [], [], []], 9: [[], [], [], [], [], []], 10: [[], [], [], [], [], []]}
Upvotes: 1
Reputation: 15872
This is the same old deep copy
vs shallow copy
thing.
Try this:
>>> a = []
>>> b = []
>>> c = []
>>> d = []
>>> e = []
>>> f = []
>>> classifiers = [a,b,c,d,e,f]
>>> import copy
>>> cvfoldacc = {k:copy.deepcopy(classifiers) for k in range(2,11)}
>>> cvfoldacc[2][0].append(8)
>>> cvfoldacc
{2: [[8], [], [], [], [], []],
3: [[], [], [], [], [], []],
4: [[], [], [], [], [], []],
5: [[], [], [], [], [], []],
6: [[], [], [], [], [], []],
7: [[], [], [], [], [], []],
8: [[], [], [], [], [], []],
9: [[], [], [], [], [], []],
10: [[], [], [], [], [], []]}
You were doing:
a = []
b = []
c = []
d = []
e = []
f = []
classifiers = [a,b,c,d,e,f]
cvfoldacc = dict.fromkeys(range(2,11), classifiers)
Now, the dictionary that is getting created, has the same list in every key, not only they look same, those are the exact same objects, having same identity
(memory location in CPython). Let's see:
>>> id(cvfoldacc[2])
171760008
>>> id(cvfoldacc[3])
171760008
And these will be same for other values as well.
So dict.fromkeys()
assigns the same value to all the keys in the dictionary, does not create a copy of it.
Now, another way, where you make a shallow copy, and this issue would be solved:
>>> cvfoldacc = {a:classifiers.copy() for a in range(2,11)}
>>> id(cvfoldacc[2])
171840616
>>> id(cvfoldacc[3])
171847688
Solved right?
>>> cvfoldacc[2][0].append(8)
{2: [[8], [], [], [], [], []],
3: [[8], [], [], [], [], []],
4: [[8], [], [], [], [], []],
5: [[8], [], [], [], [], []],
6: [[8], [], [], [], [], []],
7: [[8], [], [], [], [], []],
8: [[8], [], [], [], [], []],
9: [[8], [], [], [], [], []],
10: [[8], [], [], [], [], []]}
Apparently not!! Let's now look DEEPER. Let's look at the id
s of the lists inside the lists:
>>> id(cvfoldacc[2][0])
171810120
>>> id(cvfoldacc[3][0])
171810120
So even though list.copy()
created a copy of the outerlist, the inner lists are the same. So essentially you are appending in list: a
which is present in all the keys
so everything is getting modified.
Deepcopy
copied all the objects recursively, avoiding the issue.
Upvotes: 2