[英]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.