2

Is there a convenient way to map a function to specified keys in a dictionary?

Ie, given

d = {"a": 1, "b": 2, "c": 3}

would like to map a function, say f, to keys "a" and "c":

{"a": f(1), "b": 2, "c": f(3)}

EDIT

Looking for methods that will not update the input dictionary.

alancalvitti
  • 476
  • 3
  • 14
  • 2
    I'd do: `use_f = {'a', 'b'}` then `{k: v if k not in use_f else f(v) for k, v in d.items()}` – j-i-l Dec 20 '18 at 22:39
  • 1
    Thanks, this idea works. I wrote a variation: `def map_at_keys(d,f,keys): return {k: f(v) if k in keys else v for k,v in d.items()}` – alancalvitti Dec 21 '18 at 14:50
  • Cool, glad to help! Yes, it makes sense to put this into a function. – j-i-l Dec 21 '18 at 14:58

1 Answers1

5

You can use a dictionary comprehension:

output_dict = {k: f(v) for k, v in d.items()}

Note that f(v) will be evaluated (called) immediately and its return values will be stored as the dictionary's values.

If you want to store the function and call it later (with the arguments already stored) you can use functools.partial:

from functools import partial


def f(n):
    print(n * 2)


d = {"a": 1, "b": 2, "c": 3}

output_dict = {k: partial(f, v) for k, v in d.items()}

output_dict['b']()
# 4

If you only want specific keys mapped you can of course not use .items and just override those keys:

d['a'] = partial(f, d['a'])

or more generalized

keys = ('a', 'c')
for key in keys:
    d[key] = partial(f, d[key])
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
  • Thanks. However, and I should have stated this in the Q, that I don't want the input dictionary updated `d[key]=...`, nor necessarily instantiate a new variable d2 - eg perhaps to inspect the modified return value. Can you modify your answer? – alancalvitti Dec 20 '18 at 22:27
  • @alancalvitti So you don't want to modify the original dictionary, but you also do not want to create a new one. There is no third option... – DeepSpace Dec 20 '18 at 22:29
  • the use case is to either print the return value of this selective map eg `d.map_on_keys(f,["a","c"])` or to globally set `d2 = d.map_on_keys(f,["a","c"])` – alancalvitti Dec 21 '18 at 01:41