adding multiple new values to the same key in a dictionary

Dave Angel davea at ieee.org
Wed Aug 12 13:05:39 CEST 2009


Dave Angel wrote:
> Krishna Pacifici wrote:
>> Hi,
>> I want to be able to add multiple new values to a key in a dictionary.
>>
>> I have tried the following:
>>
>> sec_dict_clean=
>> {88: [87, 89, 78, 98], 58: [57, 59, 48, 68], 69: [79], 95: [94, 96, 85]}
>>
>> for i in range(len(sec_dict_clean.values())):
>>     for j in range(len(sec_dict_clean.values()[i])):
>>         
>> sec_dict_clean.setdefault(key,[]).append(blocks[sec_dict_clean.values()[i][j]].abundance) 
>>
>>
>> where blocks[...].abundance gives me a single value from an object,
>>
>> but this gives me the following:
>>
>> sec_dict_clean=
>> {88: [87, 89, 78, 98], 58: [57, 59, 48, 68], 69: [79], 95: [94, 96, 
>> 85, 4, 12, 11, 6, 9, 12, 11, 7, 10, 10, 12, 9, 6, 12, 15, 9, 8, 12, 
>> 15, 12, 12]}
>>
>> instead I want each abundance (starts with 4, 12...) to be associated 
>> with each of the values so that it would look like this:
>>
>> sec_dict_clean=
>> {88: ([87, 89, 78, 98], [4,12,11,6]), 58: ([57, 59, 48, 68], 
>> [9,12,11,7]), 69: ([79], [10])...}
>>
>> You can see there are several errors here (I have more things being 
>> appended than there are values in the dictionary), but I really just 
>> want to know how to add multiple values to the same key in a dictionary.
>>
>> Thanks for any help,
>> Krishna
>>
>>
>>
>>   
> You're really distorting the purposes of both dictionary and list 
> here.  It makes your code totally unreadable, which makes it hard to 
> write, and hard to debug.
>
> A dictionary is a mapping between key and value, where each key has 
> exactly one value.  You cannot add another one to it.   All you can do 
> is make the value something which is itself a collection.  Now, your 
> desired dictionary looks achievable, almost.  If you change the parens 
> (tuple) to square brackets (list), then it'll work.
>    So key 88 has a single value, which is a list of two items.  Each 
> of those items is itself a list with 4 items.  And each of those items 
> are integers.
>
> But then I got bogged down in your sample code.  I tried to simplify 
> it, replacing the first two lines with these three:
>
> for i, key in enumerate(sec_dict_clean):
>    val = sec_dict_clean[key]
>    for j, xxx in enumerate(val):
>        
> ???sec_dict_clean.setdefault(key,[]).append(blocks[sec_dict_clean.values()[i][j]].abundance) 
>
>
> But I can't make head nor tail of the third line.  You didn't have a 
> variable key, so I don't know if I'm using the same one..  Since I 
> can't figure out what you were trying to do, I can't see how to fix it.
>
> I think the problem here is you're trying to reorganize the data as 
> well as adding to it, in a single pass.  So is some previous code 
> generating the dictionary incorrectly, and instead of fixing that, 
> you're trying to reorganize it here?
>
> To make each dictionary value a list of lists:
>
> sec_dict_clean=
> {88: [87, 89, 78, 98], 58: [57, 59, 48, 68], 69: [79], 95: [94, 96, 85]}
>
> for key in sec_dict_clean:
>    sec_dict_clean[key] = [sec_dict_clean[key]]
>
> now,  the dict looks like:
> {88: [[87, 89, 78, 98, 3]], 58: [[57, 59, 48, 68]], 69: [[79]], 95: 
> [[94, 96, 85]]}
>
> At this point, if you have some interesting data to add to it, you can 
> just append a new list to
>     dict[key]
>
> In an earlier message, you mentioned fields a and b, and assuming this 
> is a similar problem, it would seem that 87 is somehow associated with 
> 4, and 89 with 12, and so on.  If that's the case, perhaps your 
> desired final structure might look more like:
>
> {88: [[87,4], [89,12], [78, 11],[98, 6],   58: [[57, 9], [59, 12], 
> [48, 11], [68, 7]],   69: ...}
>
>
> In this case, the structure is entirely different.  But the approach 
> is the same.  And at least you'd be getting closer to the object 
> approach where  [87,4] is replaced by an object of some type.
>
> BTW, please don't top-post.  When you reply to this one, put your 
> reply at the end, or sometimes interspersed.  But if you put it at the 
> beginning, it's out of order.
>
> DaveA
>
>
>
>
Look at the following (tested in Python 2.6.2).,  There are a number of 
things that could be cleaner, mainly the names of things.  I should 
never be calling something "value" unless it's a very generic routine.

<code>
class Sample(object):
    def __init__(self, mainval):
        self.mainval = mainval
        self.a = self.b = None
    def set_tags(self, a, b):
        self.a = a
        self.b = b
    def __repr__(self):
        return "<" + str(self.mainval) + " a=" + str(self.a) + " b=" + 
str(self.b) + ">"


diction2 = {88: [Sample(87), Sample(89), Sample(98), Sample(3)],
            58: [Sample(57), Sample(59), Sample(48), Sample(68)],
            69: [Sample(79)]
                 }

print diction2

for key, valuelist in diction2.iteritems():
    for item in valuelist:
        item.set_tags(12, 106)             #here's where you'd be using 
that mysterious blocks dictionary

print diction2

</code>

DaveA



More information about the Python-list mailing list