Could someone explain how the assignment to the dictionary "inverse" is happening in the case below?
def invert_dict(d):
inverse = {}
for key in d:
new_key = d[key]
inverse.setdefault(new_key, []).append(key)
return inverse
letters_in_word = {"mine": 4, "yours": 5, "ours": 4, "sunday": 6, "friend": 6, "fun": 3, "happy": 5, "beautiful": 8}
print (invert_dict(letters_in_word))
The output, of course, is correct:
{8: ['beautiful'], 3: ['fun'], 4: ['mine', 'ours'], 5: ['happy', 'yours'], 6: ['sunday', 'friend']}
Python 3.x documentation says:
setdefault(key[, default]):
If key is in the dictionary, return its value. If not, insert key with a value of default and return default. default defaults to None.
Let me use an example to illustrate what I do and do not understand:
I know that by the end of 4 I am wrong because in fact our list has been assigned to the key "5". What I don't understand is the point at which that happened - it seems like we just returned and really should have to assign with:
inverse[new_key] = inverse.setdefault(new_key, []).append(key)
However, if I run the code like that I get the error - 'NoneType' object has no attribute 'append'
.
Any explanation is appreciated - I guess I must be missing something about how the two methods are interacting.
P.S. This is my first question so apologies if the question nature/structure is not 'how things are done around here'. Let me know how to improve and I will do my best to do so!
Print statements are a very useful and easy way to understand what's happening in a program:
def invert_dict(d):
inverse = {}
for key in d:
new_key = d[key]
print('key:', key)
print('new_key:', new_key)
print('inverse before:', inverse)
value = inverse.setdefault(new_key, [])
print('inverse in the middle:', inverse)
print('value before:', value)
value.append(key)
print('value after:', value)
print('inverse after:', inverse)
return inverse
letters_in_word = {"mine": 4, "yours": 5, "ours": 4, "sunday": 6, "friend": 6, "fun": 3, "happy": 5, "beautiful": 8}
print(invert_dict(letters_in_word))
Output:
key: beautiful
new_key: 8
inverse before: {}
inverse in the middle: {8: []}
value before: []
value after: ['beautiful']
inverse after: {8: ['beautiful']}
key: yours
new_key: 5
inverse before: {8: ['beautiful']}
inverse in the middle: {8: ['beautiful'], 5: []}
value before: []
value after: ['yours']
inverse after: {8: ['beautiful'], 5: ['yours']}
key: ours
new_key: 4
inverse before: {8: ['beautiful'], 5: ['yours']}
inverse in the middle: {8: ['beautiful'], 4: [], 5: ['yours']}
value before: []
value after: ['ours']
inverse after: {8: ['beautiful'], 4: ['ours'], 5: ['yours']}
key: sunday
new_key: 6
inverse before: {8: ['beautiful'], 4: ['ours'], 5: ['yours']}
inverse in the middle: {8: ['beautiful'], 4: ['ours'], 5: ['yours'], 6: []}
value before: []
value after: ['sunday']
inverse after: {8: ['beautiful'], 4: ['ours'], 5: ['yours'], 6: ['sunday']}
key: happy
new_key: 5
inverse before: {8: ['beautiful'], 4: ['ours'], 5: ['yours'], 6: ['sunday']}
inverse in the middle: {8: ['beautiful'], 4: ['ours'], 5: ['yours'], 6: ['sunday']}
value before: ['yours']
value after: ['yours', 'happy']
inverse after: {8: ['beautiful'], 4: ['ours'], 5: ['yours', 'happy'], 6: ['sunday']}
key: fun
new_key: 3
inverse before: {8: ['beautiful'], 4: ['ours'], 5: ['yours', 'happy'], 6: ['sunday']}
inverse in the middle: {8: ['beautiful'], 3: [], 4: ['ours'], 5: ['yours', 'happy'], 6: ['sunday']}
value before: []
value after: ['fun']
inverse after: {8: ['beautiful'], 3: ['fun'], 4: ['ours'], 5: ['yours', 'happy'], 6: ['sunday']}
key: mine
new_key: 4
inverse before: {8: ['beautiful'], 3: ['fun'], 4: ['ours'], 5: ['yours', 'happy'], 6: ['sunday']}
inverse in the middle: {8: ['beautiful'], 3: ['fun'], 4: ['ours'], 5: ['yours', 'happy'], 6: ['sunday']}
value before: ['ours']
value after: ['ours', 'mine']
inverse after: {8: ['beautiful'], 3: ['fun'], 4: ['ours', 'mine'], 5: ['yours', 'happy'], 6: ['sunday']}
key: friend
new_key: 6
inverse before: {8: ['beautiful'], 3: ['fun'], 4: ['ours', 'mine'], 5: ['yours', 'happy'], 6: ['sunday']}
inverse in the middle: {8: ['beautiful'], 3: ['fun'], 4: ['ours', 'mine'], 5: ['yours', 'happy'], 6: ['sunday']}
value before: ['sunday']
value after: ['sunday', 'friend']
inverse after: {8: ['beautiful'], 3: ['fun'], 4: ['ours', 'mine'], 5: ['yours', 'happy'], 6: ['sunday', 'friend']}
{8: ['beautiful'], 3: ['fun'], 4: ['ours', 'mine'], 5: ['yours', 'happy'], 6: ['sunday', 'friend']}
Also very useful is a good debugger such as the one in PyCharm. Try that out.