Restructure dictionary (Python 2.5)

F

Fencer

Hello, I have a dictionary that has strings as keys and for each key the
associated value is a list of strings. Many of the lists contain only
one element and a given element may appear for more than one key.
What I need to do now is create a new dictionary where the strings in
the list are keys and their values is a list of which keys in the "old"
dictionary that contained them.
So I want to go from:
aa:[a, b, c]
bb:[c, d]
to
a:[aa]
b:[aa]
c[aa, bb]
d:[bb]

I tried this code:
old_dict = {'xyz':['a','b','c'],'baz':['c','d']}
new_dict = {}
for dkey, vallist in old_dict.iteritems():
for val in vallist:
if val in new_dict:
theset = new_dict[val]
theset.add(dkey)
new_dict[val] = theset
else:
new_dict[val] = set([dkey])
print new_dict

Which yields the output {'a': set(['xyz']), 'c': set(['xyz', 'baz']),
'b': set(['xyz']), 'd': set(['baz'])}, so it seems to work but I have a
feeling this is a crappy solution that's underusing Python. Please
enlighten me of a better way!

- Fencer
 
T

Tim Chase

I tried this code:
old_dict = {'xyz':['a','b','c'],'baz':['c','d']}
new_dict = {}
for dkey, vallist in old_dict.iteritems():
for val in vallist:
if val in new_dict:
theset = new_dict[val]
theset.add(dkey)
new_dict[val] = theset
else:
new_dict[val] = set([dkey])
print new_dict

Which yields the output {'a': set(['xyz']), 'c': set(['xyz', 'baz']),
'b': set(['xyz']), 'd': set(['baz'])}, so it seems to work but I have a
feeling this is a crappy solution that's underusing Python. Please
enlighten me of a better way!

In python2.5, collections.defaultdict was added which could clean
this up a bit:

import collections
# using a set to remove duplication
new_dict = collections.defaultdict(set)
for dkey, vallist in old_dict.iteritems():
for val in vallist:
new_dict[val].add(dkey)

# using a list to keep all keys
new_dict = collections.defaultdict(list)
for dkey, vallist in old_dict.iteritems():
for val in vallist:
new_dict[val].append(dkey)

If you're working in pre-2.5 python, you could use

new_dict = {}
...
# use a set()
new_dict.setdefault(val, set()).add(dkey)
# use a list()
new_dict.setdefault(val, []).append(dkey)

-tkc
 
I

imageguy

... this is a crappy solution that's underusing Python. Please
enlighten me of a better way!

- Fencer

One thing that springs to mind is using the dict method .setdefault

<untested>
for dkey, vallist in old_dict.iteritems():
for val in vallist:
new_dict.setdefault(val, set()).add(dkey)
</untested>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top