views:

111

answers:

4

How can I create another dictionary using the keys of another dictionary, and an array of values?

I thought about doing this:

zipped = zip(theExistingDict.keys(), arrayOfValues)
myNewDict = dict(zipped)

However, this doesn't quite work, each value from arrayOfValues are paired with an arbitrary key in the resulting dictionary. I don't have any control over which element from arrayOfValues is paired with which key in theExistingDict.keys().

theExistingDict looks like this:

{u'actual bitrate': 4, u'Suggested Bitrate': 3, u'title': 2, u'id': 1, u'game slot': 0}

arrayOfValues looks like this:

1.0, u'GOLD_Spider Solitaire', u'Spider\\nSolitaire', 120000.0, 120000.0

So: I would like arrayOfValues[0] to map to game slot (because in the dictionary it has value 0).

Is there an easy and elegant way to do this?

+4  A: 

As others have mentioned, a Dictionary doesn't have any order defined in it. The python docs say, "Keys and values are listed in an arbitrary order which is non-random, varies across Python implementations, and depends on the dictionary’s history of insertions and deletions."

If you're looking to use the original order that you added the items into the dictionary, you can try looking for an alternative implementation of dictionary that preserves this order -- e.g. http://www.voidspace.org.uk/python/odict.html

Polemarch
A: 

In light of the comments above, it's possible that a dictionary for theExistingDict may not be the structure you are looking for.

You may be interested in an ordered dictionary.

See also the answers to "What’s the way to keep the dictionary parameter order in Python?"

Brian M. Hunt
+4  A: 

Since your existing dictionary itself contains information on the positions of the elements in the list: you could do:

>>> exist = {u'title': 2, u'actual bitrate': 4, u'id': 1, u'game slot': 0, u'Suggested Bitrate': 3}
>>> l = [1.0, u'GOLD_Spider Solitaire', u'Spider\\nSolitaire', 120000.0, 120000.0]
>>> dict((k, l[v]) for k, v in exist.iteritems())
{u'Suggested Bitrate': 120000.0, u'game slot': 1.0, u'actual bitrate': 120000.0, u'id': u'GOLD_Spider Solitaire', u'title': u'Spider\\nSolitaire'}

or in py3k:

>>> {k: l[v] for k, v in exist.items()}
{'Suggested Bitrate': 120000.0, 'game slot': 1.0, 'actual bitrate': 120000.0, 'id': 'GOLD_Spider Solitaire', 'title': 'Spider\\nSolitaire'}
SilentGhost
Very elegant - this is the kind of solution I was looking for, thanks!
BeeBand
A: 

perhaps something more like:

from operator import itemgetter
zip( array_of_values, [ a for a, _ in sorted(existing_dict.iteritems(), key=itemgetter(1)) ] )

it can be modified further if you'd like to match index with integer, possibly with unused values...

 zipped = [ (k, a) for i, a in enumerate(array_of_values) for k, v in existing_dict.iteritems() if i == v ]
 new_dict = dict(zipped)
Autoplectic