Reputation: 721
I am very novice in python, and I am currently learning the language. I found that array of arrays ( associative arrays ) are called as dictionaries in python ({})
I am facing a problem. I need to build a dictionary and update it in a for
loop. My codes are below.
loc = {}
result = { I get the list of records from database here, which has id and status }
for res in result:
temp={}
temp['id']= res.id
temp['status'] = res.status
loc.update(temp) # this replaces the values every time, i want append
print loc
below is the result expected by me:
loc = { {'id' : 123 , 'status' : 'available' },
{ 'id' : 456 , 'status' : 'unavailable'}
}
Can someone help me. I tried with :
loc = [] # [] this works with loc.append(temp)
this gives result as :
[{'id' : 123 , 'status' : 'available'},{'id' : 456 , 'status' : 'unavailable'}]
But i need the above result with dictionary of dictionaries in python.
Upvotes: 0
Views: 2188
Reputation: 4484
You can update a dictionary by adding a new entry or a key-value pair, modifying an existing entry, or deleting an existing entry as shown below in the simple example
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
dict['Age'] = 8; # update existing entry
dict['School'] = "DPS School"; # Add new entry
print "dict['Age']: ", dict['Age']
print "dict['School']: ", dict['School']
source: iodocs
Upvotes: 0
Reputation: 155363
If id
is unique, it seems more likely that what you really want is just a dict
mapping id
to status
.
for res in result:
loc[res.id] = res.status
If you iterate over loc.viewitems()
(in Py3, just loc.items()
), you get tuple
s that pair each id
with its status
; Python uses tuple
s as sort of "anonymous lightweight objects", so it works quite similarly to the set
of dict
s you were trying to build. Used this way, you can look up values by id
efficiently (loc[someid]
will get you the associated status
if the id
exists or raise KeyError
), while still being able to efficiently iterate them:
for ID, status in loc.viewitems():
# do stuff with ID and status
A list
of dict
s makes lookup a O(n)
task (where the plain dict
is roughly O(1)
lookup), and makes iteration a little more ugly, requiring you to use operator.itemgetter
to write a similar loop for unpacking, or requiring manual lookup of the both id
and status
for each item, which is ugly to say the least. It's also much less efficient memory-wise; each two item dict
pays fairly substantial memory overhead relative to a single larger dict
.
One other option to consider, if you really want this to behave more like JS objects, is using collections.namedtuple
. It's sort of dict
like; you access attributes with dot syntax, not keys with bracket syntax, but it's much more memory efficient, and it's immutable, so it can go in a set
:
from collections import namedtuple
Record = namedtuple('Record', 'id status')
loc = {Record(res.id, res.status) for res in result}
You can then use the namedtuple
like a regular tuple
(so for ID, status in loc:
works), or use named attribute access instead:
for record in loc:
print(record.id, record.status)
Upvotes: 2
Reputation: 29876
What you say is your desired output:
loc = {
{'id' : 123 , 'status' : 'available' },
{'id' : 456 , 'status' : 'unavailable'}
}
would not be a dict
. It would be a set
if it worked at all.
But a set
can't contain a dict
because it's not hashable. A set can only contain hashable elements because it uses the hash for fast lookups. (A hashable item would either be completely immutable or any mutation it experiences would not affect the hash. Note that not affecting the hash implies it also doesn't affect equality. Generally, it's just easier to ensure hashable things are immutable.)
In a dictionary, you must have a key and a value. Your desired output does not describe a key for each inner dict
, so a dict
isn't the data structure you want. What you probably want is exactly what you found out works:
loc = [
{'id' : 123 , 'status' : 'available' },
{'id' : 456 , 'status' : 'unavailable'}
]
This is a list
. A list
is the go-to data structure for holding a sequence of elements. You can iterate over it:
for i in loc:
print(i)
or access elements of it via index:
loc[2]
This is probably what you want. There's more you can do with it, like slice it, but I won't get into everything here.
The update
function you are calling in your sample code is used for taking each key in the input dict
and either adding the key/value pair to it or updating the value for an existing key. You might think of this as "merging" the argument dict
into the one before the dot. That's why it overwrote all the values each time; that's how it's supposed to work. Python's documentation is pretty good; you want to get in the habit of consulting it whenever something doesn't behave as you expect.
Upvotes: 1