1

Can one write a concise expression that evaluates to an existing dictionary except with some of the elements replaced (modified, substituted)? Example:

a = {'x': 3, 'y': 8}

I'd like to write an expression that evaluates to a dict with the 'x' element's value incremented by one:

{'x': 4, 'y': 8}

I don't want to modify a (as in a['x'] += 1); I want to treat a as immutable. I could do this:

a = {'x': 3, 'y': 8}
a_copy = a.copy()
a_copy['x'] += 1

then reference a_copy. But is there a more succinct approach that doesn't require an additional variable? (I need to reference the resultant dictionary only once.) Performance isn't a concern.

Dictionary comprehensions can be used to generate a new dictionary, but I want an expression that returns a slight variation of an existing dictionary.

Larry Ruane
  • 137
  • 6
  • `a_copy = {k: v+1 if k=='x' else v for k, v in a.items()}` .. looking for a dupe – pault Jun 07 '19 at 19:46
  • 1
    i will say, your method is pretty small and clear in its intents, and readable too. – Paritosh Singh Jun 07 '19 at 19:48
  • 1
    Possible duplicate of [Python Dictionary Comprehension](https://stackoverflow.com/questions/14507591/python-dictionary-comprehension) and [Does Python have a ternary conditional operator?](https://stackoverflow.com/questions/394809/does-python-have-a-ternary-conditional-operator) – pault Jun 07 '19 at 19:50

2 Answers2

2

Kind of obscure but does the job, only works since Python 3.5:

a = {'x': 3, 'y': 8}
a_copy = {**a, 'x': a['x'] + 1}
print(a_copy)
# {'x': 4, 'y': 8}

A better approach is using a comprehension:

a_copy = {k: v + 1 if k == 'x' else v for k, v in a.items()}
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
1

You can use a dictionary comprehension, only incrementing values for the keys you want to increment

#I took the keys in a list if you want to increment more keys
keys_to_incr = ['x']
a = {'x': 3, 'y': 8}

#Increment value if key falls in keys_to_incr, else leave value as0is
a_copy = {k: v+1 if k in keys_to_incr else v for k, v in a.items()}
print(a_copy)

The output will be

{'x': 4, 'y': 8}
Devesh Kumar Singh
  • 20,259
  • 5
  • 21
  • 40