2011-03-27 86 views
0

我已經寫了,像這樣一些代碼:爲什麼python詞典表現這種方式?

class Invite(models.Model): 
    STATE_UNKNOWN = 0 
    STATE_WILL_PLAY = 1 
    STATE_WONT_PLAY = 2 
    STATE_READY = 3 
    STATE_CHOICES = ((STATE_UNKNOWN, _("Unknown")), 
        (STATE_WILL_PLAY, _("Yes, I'll play")), 
        (STATE_WONT_PLAY, _("Sorry, can't play")), 
        (STATE_READY, _("I'm ready to play now"))) 
    ... 


    def change_state(self, state): 
     assert(state in dict(Invite.STATE_CHOICES)) 

此代碼的工作就像我想讓它,但我很好奇,爲什麼是這樣工作的。無可否認,這樣做確實非常方便,但似乎我可能錯過了一些基本的哲學原理。

如果我嘗試類似:

dict((1,2,3), (2,2,3), (3,2,3)) 
ValueError: dictionary update sequence element #0 has length 3; 2 is required 

它不會創建一個字典,看起來像

{1: (2,3), 2: (2,3), 3: (2,3)} 

所以一般模式是不是要採取元組的第一部分關鍵和其餘的價值。是否有導致這種行爲的一些基本的基礎,或者只是,如果它確實會很方便......

+0

這是真的很難看。你爲什麼不首先定義一個字典而不是從一個元組元組構造一個字典? – 2011-03-27 18:12:53

+0

Django選擇字段應該是一個二元組序列。關於這點我可以做的不多。 – boatcoder 2011-03-27 18:25:54

回答

3

我認爲這有些明顯。在你的例子中,(1,2,3)是一個單一的對象。所以字典背後的想法是將key映射到value(即對象)。

因此考慮輸出:

>>> dict(((1,(2,3)), (2,(2,3)))).items() 
[(1, (2, 3)), (2, (2, 3))] 

但你也可以做這樣的事情:

>>> dict((((1,2),3), ((2,2),3))) 
[((1, 2), 3), ((2, 2), 3)] 

key實際上是一個對象呢!在這種情況下也是一個元組。

所以在你的例子:

dict((1,2,3), (2,2,3), (3,2,3)) 

你怎麼知道,每個元組的部分是關鍵,這是價值?

如果你覺得這惱人的,這是一個簡單的解決寫你自己的構造函數:

def special_dict(*args): 
    return dict((arg[0], arg[1:]) for arg in args) 

此外,爲了雷夫的評論,你應該定義字典馬上:

class Invite(models.Model): 
    STATE_UNKNOWN = 0 
    STATE_WILL_PLAY = 1 
    STATE_WONT_PLAY = 2 
    STATE_READY = 3 
    STATE_CHOICES = dict(((STATE_UNKNOWN, _("Unknown")), 
        (STATE_WILL_PLAY, _("Yes, I'll play")), 
        (STATE_WONT_PLAY, _("Sorry, can't play")), 
        (STATE_READY, _("I'm ready to play now")))) 
    ... 


    def change_state(self, state): 
     assert(state in Invite.STATE_CHOICES) 

如果您想要遍歷各個狀態,所有你需要做的是:

for state, description = Invite.STATE_CHOICES.iteritems(): 
    print "{0} == {1}".format(state, description) 

The construction在您的change_state函數中的字典是不必要的昂貴。

當你定義Django的領域,只是做:

models.IntegerField(sorted(choices=Invite.STATE_CHOICES.iteritems())) 
+0

一旦我知道它是如何工作的,它對我來說也是顯而易見的。我只是在想,語言的實現者對此應該如何表現出來。有時候瞭解事物的原因會導致對其他事物的更好理解。 – boatcoder 2011-03-27 18:27:47

+0

Guido是一個聰明的傢伙,我猜? :) – milkypostman 2011-03-27 18:32:17

3

dict的構造函數接受(除別的之外)一組(key, value)元組。你的第二個例子傳遞了長度爲3而不是2的元組列表,因此失敗了。

dict([(1, (2, 3)), (2, (2, 3)), (3, (2, 3))]) 

但是將創建字典

{1: (2, 3), 2: (2, 3), 3: (2, 3)} 
+1

他並沒有問如何去做他想做的事情,而是在問爲什麼'dict'構造函數是按照它的方式設計的。 – milkypostman 2011-03-27 18:23:53

+0

@milky,在這個問題中給出了答案。它以這種方式工作,因爲這是一種構建字典的非常方便的方式。 – 2011-03-27 20:18:28

1

一般模式就是這樣的:你可以創建一個列表的字典(一般:迭代器)的,視爲(鍵,值)。任何更長的將是任意的:爲什麼(1,2,3) - > {1:(2,3)}而不是(1,2,3) - > {(1,2):3}?

此外,雙< - >字典轉換顯然是雙向的。用三元組不能(參見上面的例子)。

相關問題