2016-12-26 23 views
1

有人可以解釋如何在下面的情況下發生字典「逆」的分配?setdefault()方法在這個逆向字典實現中如何工作?

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)) 

輸出,當然,是正確的:

{8:[ '美麗'],3:[ '樂趣'],4:[ '我的', '我們的'],5 :[ '快樂', '你'],6: '星期天', '朋友']}

的Python 3.x的文件說:

setdefault(鍵[,默認值]):

如果鍵在字典中,則返回其值。如果沒有,則插入具有默認值的鍵並返回默認值。默認默認爲None。

讓我用一個例子來說明我做什麼和不理解:

  1. 假設new_key = 「快樂」
  2. new_key有5
  3. setdefault的值()被調用讓我們假設5已經在「你的」字典中了(據我所知,由於字典無序,這不一定是這種情況,但我們假設)並將返回[「yours」] (我的猜測這裏發生的事情稍有不同,所以事實上並非如此「inverse.setdefault(5,[])」已返回[「yours」],就是這樣)
  4. append()被調用並且[「yours」] - > [「yours」,「happy」] - 這就是我們留下的。

我知道在4月底我錯了,因爲實際上我們的列表已經被分配給了鍵「5」。我不明白的是,發生在哪個點 - 好像我們剛剛回來,真的應該與分配:

inverse[new_key] = inverse.setdefault(new_key, []).append(key) 

但是,如果我運行代碼一樣,我得到的錯誤 - 'NoneType' object has no attribute 'append'

任何解釋讚賞 - 我想我必須錯過這兩種方法如何相互作用的東西。

P.S.這是我的第一個問題,如果問題的本質/結構不是'這裏的事情是怎麼做的',那麼我很抱歉。讓我知道如何改進,我會盡我所能去做!

+1

請注意'list.append'總是返回'None'。 – mgilson

+0

@MoinuddinQuadri我在發佈之前閱讀過這些內容,但在那裏看不到我的問題的答案。我會重新閱讀,這可能是對我的問題的答案在那裏 - 但我不能「看」/理解相關位。將再試一次! – cjjob

+0

@mgilson啊,好的,這就解釋了爲什麼我的逆[new_key]行永遠無法解決問題。 – cjjob

回答

0

打印語句是理解什麼是程序中發生的一個非常有用而簡單的方法:

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)) 

輸出:

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']} 

也非常有用的是一個很好的調試器,如一個在PyCharm 。試試看。

+0

感謝您的提問 - 追蹤問題很有幫助。對我來說真正沒有意義的一步是「反過來:{8:['beautiful']}'。我看不到如何調用改變變量'value'的'value.append(key)'也改變'inverse'。調試器提示也非常感謝! – cjjob

+0

@cjjob因爲變量'value'和'inverse'內的列表值是*相同的對象*,而不是單獨的副本。對'one'的任何改變也會改變'other',因爲它們是一樣的。 'value is inverse [new_key]'返回'True'。 –

+0

@cjjob'value'不是一個獨立或孤立的列表,是對真實列表的引用,它在內存中的某個位置,同樣適用於'inverse'內的列表。檢查這個主題的講座:http://nedbatchelder.com/text/names.html – Copperfield