pythonsetsetdefault

python setdefault(key,set())).update(... returns None


I'm having a problem with setdefault and unions not working like I expect them to. My code looks like:

#!/usr/bin/python3.3
kanjidic = {
    '恕': {'radical':{'multi_radical': {'口心女'}}},
    '靛': {'radical':{'multi_radical': {'亠宀月疋二青土'}}},
}
k_rad = {}
for k,v in kanjidic.items():
    if 'radical' in v and 'multi_radical' in v['radical']:
        print (k, set(v['radical']['multi_radical']))
        k_rad[k] = k_rad.setdefault(k, set()).update(
            set(v['radical']['multi_radical']))
    print('>>', k_rad[k])

The print output looks like:

恕 {'口心女'}
>> None
靛 {'亠宀月疋二青土'}
>> None

If I substitute the two lines below for setting k_rad:

k_rad[k] = k_rad.setdefault(k, set())
k_rad[k].update(set(v['radical']['multi_radical']))

My output looks like this:

靛 {'亠宀月疋二青土'}
>> {'亠宀月疋二青土'}
恕 {'口心女'}
>> {'口心女'}

If I understand setdefault, (which obviously I don't) the output should be the same,right? What am I missing? Why am is dict.setupdate(key,set()).update(set(...)) returning None?

As pointed out below, the problem is that update returns None. I really didn't understand how update and setdefault work together. Since setdefault sets the dict to the default if we're creating a new dict element and returning the the hash and update updates the element I didn't need the assignment. All I really needed was:

for k,v in kanjidic.items():
    if 'radical' in v and 'multi_radical' in v['radical']:
        k_rad.setdefault(k, set()).update(v['radical']['multi_radical'])

Thanks for the assistance!


Solution

  • dict.setdefault returns a set in your case. And set.update is an in-place operation, which means it changes the original set and returns None. So if you assign the result to a variable you just assign it a None.