PyNEwbie
PyNEwbie

Reputation: 4940

Dictionaries in Python

I am trying to get to speed on the use of dictionaries. I spent three hours last night searching the web for examples similar to some of the things I am trying to do. For example, suppose I have two dictionaries (actually I have two lists of dictionaries).

d1={key1:1, key2:2}
d2={key1:1, key2:'A', key4:4}

I want to update d1 so it looks like the following:

d1={key1:1, key2:[2,'A'], key3:3, key4:4}

Ii can't seem to find adequate examples to get me started. I have a fair number of books and I also reviewed them but they all seem to have the same type of examples that I am finding on the web.

Does anyone know of a place or a book that has explicit examples and descriptions of how to use dictionaries?

I think one of the problems I am having is that I am not understanding how references are maintained as I access the dictionary.

I can check to see if the two dictionaries have a common key:

for k in d1.keys():
    for k2 in d2.keys():
        if k==k2:
            print 'true'

but if they do I can't seem to combine the values into a list.

More than a direct answer to this particular example I would appreciate any suggestions about places where there are good examples of using dictionaries.

Upvotes: 5

Views: 2095

Answers (9)

Kurt Campher
Kurt Campher

Reputation: 815

Here is another variation.

d1 = {'key1'=1, 'key2'=2}
d2 = {'key1'=1, 'key2'='A', 'key4'=4)
d = d2
for k, v in d.iteritems():
... if k in d1.keys() and v!=d1[k]:
... d[k] = [d1[k], v2]
d
{'key2': [2, 'A'], 'key1': 1, 'key4': 4}

Upvotes: 0

lacker
lacker

Reputation: 5550

Maybe this is a bit awkward to do because the data structure you are trying to create is not as natural as it could be. For example instead of having some values be lone values, and some be lists, why not keep everything in lists? E.g.

{'key1': [1], 'key2': [2, 'A'], 'key4': [4]}

It is possible in Python to have a collection of mixed data types but your code will often be cleaner if you keep it coherent. If you use this sort of data structure, inserting is as easy as

# Inserting a (key, value) pair
if key in my_dict:
    my_dict[key].append(value)
else:
    my_dict[key] = [value]

Upvotes: 0

S.Lott
S.Lott

Reputation: 391818

Try this:

import collections
merged = collections.defaultdict(list)
for k in d1:
   merged[k].append( d1[k] )
for k in d2:
   merged[k].append( d2[k] )

This may be what you're looking for.

Or possibly this.

import collections
merged = collections.defaultdict(set)
for k in d1:
   merged[k].add( d1[k] )
for k in d2:
   merged[k].add( d2[k] )

Upvotes: 13

jfs
jfs

Reputation: 414079

A variation on @SilentGhost's answer (all other answers produce wrong dictionaries):

>>> d1 = dict(key1=1, key2=2)
>>> d2 = dict(key1=1, key2='A', key4=4)
>>> d = dict(d1)
>>> for k, v2 in d2.iteritems():
...     v = d.get(k, None)
...     d[k] = [v, v2] if v is not None and v != v2 else v2
...
>>> d
{'key2': [2, 'A'], 'key1': 1, 'key4': 4}

Upvotes: 0

SilentGhost
SilentGhost

Reputation: 319531

I believe here is what you want:

>>> d1={'key1':1, 'key2':2}
>>> d2={'key1':1, 'key2':'A', 'key4':4}
>>> d = {}
>>> d.update(d1)
>>> for i in d2:
        if i in d and d2[i] != d[i]:
            d[i] = [d[i], d2[i]]
        else:
            d[i] = d2[i]            
>>> d
{'key2': [2, 'A'], 'key1': 1, 'key4': 4}

Upvotes: 4

hasen
hasen

Reputation: 166112

well, for your first case, you might want a helper that combines two objects into a list of two objects, and two lists into one list containing items from the two lists,

This is assuming of course, that you always merge keys into lists, but you don't want your keys to end up being "lists of lists"

def listify( obj ): 
   if type(obj) != type([]): return [obj]
   else: return obj

def merge( v1, v2 ):
    return listify(v1) + listify(v2)

#so now you can merge two dictionaries:
dict1 = dict(a = 2, b = 5, c = 7 )
dict2 = dict(b = 4, d = 9, f = 10 )
dikt = {}

for k in set( dict1.keys() + dict2.keys() ):
    dikt[k] = merge( dict1.get(k, []), dict2.get(k, []) )
#resutls in:
# {'a': [2], 'c': [7], 'b': [5, 4], 'd': [9], 'f': [10]}

You may notice, dict.keys() returns a list of keys, set returns a list without duplicate items, so set( d1.keys(), d2.keys() ) returns union of the keys of d1 and d2

Upvotes: 0

David Wolever
David Wolever

Reputation: 154454

One good place to start is by getting iPython (easy_install ipython) then poking around with tab completion, ? and dir:

In [2]: dir {}
------> dir({})

Out[2]: 
['__class__',
 ...
 'keys',
 'pop',
 'popitem',
 'setdefault',
 'update',
 'values']

In [3]: {}.update?
Type:       dict
Base Class: <type 'dict'>
String Form:    {}
Namespace:  Interactive
Length:     0
Docstring:
    dict() -> new empty dictionary.
    dict(mapping) -> new dictionary initialized from a mapping object's
        (key, value) pairs.
    dict(seq) -> new dictionary initialized as if via:
        d = {}
        for k, v in seq:
            d[k] = v
    dict(**kwargs) -> new dictionary initialized with the name=value pairs
        in the keyword argument list.  For example:  dict(one=1, two=2)

(just for example)

Anyway, your problem with checking keys common between the two dictionaries: there are a few things to consider (maybe look at the set class?), but here's how I'd do it:

common_keys = [k for k in dict1 if k in dict2]

(ie, "each key k in dict1 if that key is also in dict2") (note, too, that testing for dictionary membership is an O(1) operation, so this will run in O(|dict1|))

edit: alright, so this doesn't solve the problem of merging the two dicts into one with lists... But Lott's answer is good for that, or you could use the setdefault method:

new = {}
for (k, v) in dict1.items():
    new.setdefault(k, []).append(v)
for (k, v) in dict2.items():
    new.setdefault(k, []).append(v)

Upvotes: 6

Ben Hayden
Ben Hayden

Reputation: 1379

Python dictionaries also work much like associative arrays in PHP, if you have any experience in that language.

The Built-in Types page in the Python docs also has a good section on dictionaries, and the section also has a list of functions available for them:

http://docs.python.org/library/stdtypes.html#mapping-types-dict

Upvotes: 1

Related Questions