簡體   English   中英

為什么python dict這樣表現呢?

[英]Why does python dict behave this way?

我有一些這樣寫的代碼:

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

因此,通常的模式是不要以元組的第一部分作為鍵,其余部分作為值。 是否有一些導致這種現象的根本原因,或者只是,如果這樣做確實會很方便。

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

另外,對於Rafe的評論,您應該立即定義字典:

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)

change_state函數中構造字典的過程不必要地昂貴。

定義Django字段時,只需執行以下操作:

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

一般的模式是只這樣的:你可以從一個列表的字典(一般:迭代器) ,視為(鍵,值)。 更長的東西將是任意的:為什么(1,2,3)-> {1:(2,3)}而不是(1,2,3)-> {(1,2):3}?

此外,pairs-dict轉換顯然是雙向的。 使用三元組則不可能(請參見上面的示例)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM