This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Dictionary defaults .get(), .pop(), .setdefault()
Type: behavior Stage: resolved
Components: Versions: Python 3.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: remi.lapeyre, vykouk
Priority: normal Keywords:

Created on 2019-05-24 09:38 by vykouk, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
Dictionary_Defaults.py vykouk, 2019-05-24 09:38
Messages (2)
msg343362 - (view) Author: Vykouk (vykouk) Date: 2019-05-24 09:38
The methods .get(), .pop(), .setdefault() evaluate defaults even though the key already exists in the dictionary:

# -*- coding: utf-8 -*-

def deflt(x):
    print('\nKey', x, 'is not in the dictionary')
    return 'Default'

dicti = {1:'one', 2:'two', 3:'three'}

key = 2
print('\ndicti \t\t', dicti)
print('\t\t key =',key)

print('get \t\t',     dicti.get(key, deflt(key)))
print('setdefault \t',dicti.setdefault(key, deflt(key)))
print('dicti \t\t',   dicti)
print('pop \t\t',     dicti.pop(key, deflt(key)))
print('dicti \t\t',   dicti)
print('setdefault \t',dicti.setdefault(key, deflt(key)))
print('dicti \t\t',   dicti)

'''
Printed outputs:

Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 14:57:15) [MSC v.1915 64 bit (AMD64)]
Type "copyright", "credits" or "license" for more information.

IPython 7.1.1 -- An enhanced Interactive Python.

runfile('C:/Temp/Smazat/Dictionary_Defaults.py', wdir='C:/Temp/Smazat')

dicti            {1: 'one', 2: 'two', 3: 'three'}
                 key = 2

Key 2 is not in the dictionary                 #  ???        
get              two

Key 2 is not in the dictionary                 #  ???
setdefault       two
dicti            {1: 'one', 2: 'two', 3: 'three'}

Key 2 is not in the dictionary                 #  ???
pop              two
dicti            {1: 'one', 3: 'three'}

Key 2 is not in the dictionary
setdefault       Default
dicti            {1: 'one', 3: 'three', 2: 'Default'}

'''
msg343363 - (view) Author: Rémi Lapeyre (remi.lapeyre) * Date: 2019-05-24 09:45
Hi @vykouk, Python evaluates arguments before calling functions so

>>> dicti.get(key, dflt(key))

is equivalent to:

>>> arg = dflt(key)
>>> dicti.get(key, arg)

Notive how dflt() is called before .get()

This is how all functions work in Python, not just dict methods.

You can change your code like so to make it work:

>>> if key in dicti:
>>>     x = dicti[key]
>>> else:
>>>     x = dflt(key)

or use defaultdict instead of setdefault which will take a callable to generate the default value.

I don't think there is a bug and we can close this issue.
Have a nice day.
History
Date User Action Args
2022-04-11 14:59:15adminsetgithub: 81214
2019-05-24 09:47:43SilentGhostsetstatus: open -> closed
resolution: not a bug
stage: resolved
2019-05-24 09:45:20remi.lapeyresetnosy: + remi.lapeyre
messages: + msg343363
2019-05-24 09:38:42vykoukcreate