Appending a Dictionary to a List - I See a Pointer Like Behavior

Appending a dictionary to a list - I see a pointer like behavior

You are correct in that your list contains a reference to the original dictionary.

a.append(b.copy()) should do the trick.

Bear in mind that this makes a shallow copy. An alternative is to use copy.deepcopy(b), which makes a deep copy.

Having trouble appending dictionary values to list in python

Try doing this:

for value in playerDict.values():
basicList.append(value)
print(basicList)

Rather than:

for value in playerDict.values():
basicList.append(playerDict.values)
print(basicList)

When you try to append playerDict.values into the list, you were effectively trying to append value of the playerDict object in the object form and not what you stored in the key of the dictionary (and hence you were getting [<built-in method values of dict object at 0x103a03d48>, <built-in method values of dict object at 0x103a03d48> ). Whereas, when you append value, it appends the actual values of the keys stored in your dictionary.

Hope, it helps.

Incorrectly appending/concat. to list at bottom of nested Python dictionary

Like @Mark says you need to use copy...

from copy import deepcopy as dc

d = {"p": [], "d": []}
d = {value: dc(d) for value in [1,2,3]}
d = {value: dc(d) for value in ["h", "i"]}

d["h"][1]["p"].append("Please Help")

print(d)
#{'h': {1: {'p': ['Please Help'], 'd': []}, 2: {'p': [], 'd': []}, 3: {'p': [], 'd': []}}, 'i': {1: {'p': [], 'd': []}, 2: {'p': [], 'd': []}, 3: {'p': [], 'd': []}}}

Python list referencing same dictionary

The pointer-like behavior is actually happening all the time. It's just that immutable types are safe; they always get replaced, even when you use operations (like +=) that logically mutate in place, but are not implemented that way for immutable objects.

You'll see this problem any time you repeatedly append the same object. In:

list_val=[]
local_dict={}
for val in ['a', 'b', 'c']:
local_dict['first']=val
list_val.append(local_dict)
print(list_val)

you never rebind local_dict to a new object, so it's always the same dict, and you keep appending that same dict over and over. By contrast, in:

list_val=[]
for val in ['a', 'b', 'c']:
local_dict={}
local_dict['first']=val
list_val.append(local_dict)
print(list_val)

the line local_dict={} is rebinding the name local_dict to a completely new dict, unrelated to the one it used to be bound to.

As I mentioned, immutable types will behave "safely", so you can't just look at a portion of the code and know if it's safe without knowing the types involved. For example:

list_val = []
for val in ['a', 'b', 'c']:
x += val
list_val.append(x)
print(list_val)

is entirely safe (inserting three unrelated str) if x is a str (immutable), but will insert three references to the same list if x is a list (mutable). If you're not sure, and need to make sure independent versions are inserted no matter what, you can copy (deep for safety, shallow for performance if you know only shallow copies are needed) at the moment of insertion, by importing the copy module, and replacing:

    list_val.append(x)

with:

    list_val.append(copy.deepcopy(x))

As it happens, for immutable types, copy.deepcopy is typically inexpensive (it pretends to copy, but doesn't actually do so, since it doesn't need to), so in cases where safety is paramount, it's a way of removing all doubt, without significantly reducing the performance when the types involved were already safe.

Python: List of dictionary stores only last appended value in every iteration

Let's review the loop body logic step by step:

  1. take one of the dicts
  2. modify it
  3. append it to the end of the list

So the key point you missed is that you modify and append the same object that was selected on the first step. And at the end of the snippet word_db2 contains six object refs, but only two unique. As a result, the output shows similar rows.

You can make a shallow copy of a dict before modifying and appending it:

for j in range(1, 4):
i = dict(i)
i['Card Type'] = 'Type '+str(j)
i['Card Key'] = key
print(i)

word_db2.append(i)
key += 1

As further note, if the dict contains other mutable objects like nested dicts, you should make a deep copy:

import copy
old_dict = {'a': [1, 2, 3], 'b': [4, 5, 6]}
new_dict = copy.deepcopy(old_dict)
old_dict['a'][1] = 7
new_dict['a'][1] # 2

Why? - Constructing a list of dictionaries from a loop doesn't work unless the dictionary is recreated on every iteration

Like other people said,Python will pass the reference.But you could do like:

for i in range(1, 4):
d['index'] = i
l.append(d.copy())

To get the result you want.

Adding dict to list within for-loop

You have a random return statement within the run_CSV function, and when you hit that your functions returns nothing - None

When your main funcion tries to do len on that None you will get that error. Since this is part of a loop i'm guessing you meant to use break there and not return

It should look like this:

    for row in ed_reader:
if not row[0] and not row[1]:
print('\n%i records written to csv' % record_count
+ '\n%i valid emails found' % valid_email_count)
break # formerly "return" was here

Issue with pop() and append()

This is OK - because res will hold the same reference as s(to the same object- in this case the array).

To solve this problem use this:

res = []
s = [1,2,3,4,5,6]
s.pop()
res.append(list(s))
print res
s.pop()
res.append(list(s))
print res

also take a look at :

How to clone or copy a list?

python: Appending a dictionary to a list - I see a pointer like behavior

Is it possible to have nested dictionary using setdefault, appending to a list?

Here's a simple example of what I think you are trying to achieve:

>>> rows = [[1,2,3], [1,2,4], [1,3,3], [1,3,5], [2,3,9], [2,3,5]]
>>> ret = {}
>>> for row in rows:
... ret.setdefault(row[0], {}).setdefault(row[1], []).append(row[2])
...
>>> ret
{1: {2: [3, 4], 3: [3, 5]}, 2: {3: [9, 5]}}

How does it work? For each row:

  1. We look for row[0] in ret keys. If it is not present, we add the pair (row[0], {}) to the dict, {} being the nested dict. It it is present, we continue.
  2. The value row[1] is the key of the nested dict. We look for it in ret[row[0]] (the first setdefault return): if it is not present, we add an empty list.
  3. We add the value row[2] to the list ret[row[0]][row[1]]

Remember that:

ret.setdefault(row[0], value_if_absent).func()

Means:

if row[0] not in ret:
ret[row[0]] = value_if_absent

ret[row[0]].func()

Usaully, value_if_absent is a container and func is one of append, extend, update, ... methods. But func may also be a setdefault to create a new container if needed.

Why the value of the first appended dictionary is changed when a second one is appended?

Both dictionaries have a reference to the same list. The clear method only mutates the original list. It doesn't create a new one. Change the clear call to this:

lista_service_reports = []

This will start a whole new list to store in the second dictionary.



Related Topics



Leave a reply



Submit