shikhanshu
shikhanshu

Reputation: 1548

Python dict get function not doing the right thing?

I thought that the .get(key, default=?) function will look at the default part only if key is not in the dict.

What I want to do is, see if a key exists in my main dictionary, if not, see if it exists in backup dictionary, and raise KeyError if it is neither in main or backup.

So, literally translating the above English statement to Python, I wrote: val = mainDict.get(key, backupDict[key])

This way, if mainDict doesn't have key, it will look it up in backupDict and raise exception if it's not there either, because I am not using get for backupDict lookup.

What is happening is, even before checking if mainDict has the key or not, Python is raising exception that it is not in backupDict. Yeah, it is not there, because it is there in mainDict !!

Why is this happening?

Upvotes: 3

Views: 865

Answers (2)

Laurent LAPORTE
Laurent LAPORTE

Reputation: 22982

Yes, the dict.get function return default if the key is not in the dictionary. But default is evaluated.

You can use an intermediate dictionary like this.

main = dict(a=5, c=3)
backup = dict(a=6, b=9, c=4)

intermediate = dict(backup, **main)
print(intermediate['a'])
print(intermediate['b'])

You get:

5  # from the ``main``dict,
9  # from the ``backup dict``.

And with:

print(intermediate['d'])

You get an exception:

Traceback (most recent call last):
  File "python", line 9, in <module>
KeyError: 'd'

Upvotes: 2

BrenBarn
BrenBarn

Reputation: 251428

The arguments to a function call are evaluated before the call is made. When you use backupDict[key] as an argument, that has to be evaluated so the result can be passed to get. The default argument is always evaluated; it's just not always returned.

If you don't want to evaluate it, you could use some alternative formulation, like:

mainDict[key] if key in mainDict else backupDict[key]

This will only evaluate one or the other.

Upvotes: 5

Related Questions