views:

253

answers:

4

What is the "most pythonic" way to build a dictionary where I have the values in a sequence and each key will be a function of its value? I'm currently using the following, but I feel like I'm just missing a cleaner way. NOTE: values is a list that is not related to any dictionary.

for value in values:
    new_dict[key_from_value(value)] = value
+16  A: 

dict((key_from_value(value), value) for value in values)

is shorter, at least.

Hank Gay
... and pythonic!
Torsten Marek
+11  A: 
>>> l = [ 1, 2, 3, 4 ]
>>> dict( ( v, v**2 ) for v in l )
{1: 1, 2: 4, 3: 9, 4: 16}

In Python 3.0 you can use a "dict comprehension" which is basically a shorthand for the above:

{ v : v**2 for v in l }
kurosch
Is this around in 2.6 via some import tricker?
Hank Gay
It was going to be, but IIRC nobody got around to it in time.
Kiv
The last I heard, dict comprehensions were coming in 2.7; I can't wait!
Hank Gay
A: 

This method avoids the list comprehension syntax:

dict(zip(map(key_from_value, values), values))

I will never claim to be an authority on "Pythonic", but this way feels like a good way.

Chris Cameron
In this case, where there's a function already defined to get the key, I'd say either approach is nice. If the zip/map required a lambda as well, that'd tip the balance in favour of a comprehension.In general, if a map or filter requires a lambda, you're better off with a comprehension.
wilberforce
+3  A: 

Py3K:

{ key_for_value(value) : value for value in values }
vartec