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:
- take one of the dicts
- modify it
- 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
:
- We look for
row[0]
inret
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. - The value
row[1]
is the key of the nested dict. We look for it inret[row[0]]
(the firstsetdefault
return): if it is not present, we add an empty list. - We add the value
row[2]
to the listret[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
Function Changes List Values and Not Variable Values in Python
Making a Countdown Timer with Python and Tkinter
Unpickling a Python 2 Object with Python 3
Check If Item Is in an Array/List
A Good Way to Get the Charset/Encoding of an Http Response in Python
How to Compare String and Integer in Python
Why Do I Get Typeerror: Can't Multiply Sequence by Non-Int of Type 'Float'
Transparent Background in a Tkinter Window
Can Python Pickle Lambda Functions
What Does a for Loop Within a List Do in Python
How to Redirect Stdout and Stderr to Logger in Python
Unsupported Operand Type(S) for +: 'Int' and 'Str'
What Is the Most Pythonic Way to Pop a Random Element from a List
Python - Is a Dictionary Slow to Find Frequency of Each Character
Coalesce Values from 2 Columns into a Single Column in a Pandas Dataframe