简体   繁体   中英

Difference between setdefaultkey() and just checking if a value already exists in a dictionary?

Recently, I was trying to fix a memory leak in my python code, and I managed to work out that the source of the leak was coming from this bit of code (abstraction):

>>> values = list
>>> a = dict

if key in a:
  a[key].extend(values)
else:
  a[key] = values

Someone suggested that I should use setdefaultkey() instead. Upon implementing it, my memory leak was fixed:

a.setdefaultkey(key,[])
a[key].extend(values)

But I don't really understand why. Could someone shed some light on why my first code was creating objects that weren't being properly garbage collected and what the difference is with the latter code?

I'm asking partly out of curiosity and partly because I need to fix another similar memory leak of the same nature where setdefaultkey() isn't going to work.

I would not call that a "memory leak", but in the first case, the first time a key is added to the dict, the variable itself is referenced by the dict , so issues may arise if values is modified. For example

a = dict()

key = 'newkey'
values = [1,2,3]

if key in a:
  a[key].extend(values)
else:
  a[key] = values

print(a[key])
values[1] = 'Ooops!'
print(a[key])

results in

[1, 2, 3]
[1, 'Ooops!', 3]

setdefault behavior could be mimicked by:

def bogus_setdefault(d: dict, key, value):
    if key in d:
        return d[key]
    d[key] = value

so, a.setdefault(key,[]) checks that key exist, and if it does not it inserts it into the dict with a empty list value. This way, when you call a[key].extend(values) on the next line, you are sure that the key exists and that it holds a list

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM