简体   繁体   中英

Python update dictionary into dictionary

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.

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)

What you say is your desired output:

loc = {
    {'id' : 123 , 'status' : 'available' },
    {'id' : 456 , 'status' : 'unavailable'}
}

would not be a dict . It would be aset 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM