2012-12-06 33 views
3
package main 

import "fmt" 

func main(){ 
    sample := map[string]string{ 
    "key1":"value1", 
    "key2":"value2", 
    "key3":"value3", 
    } 
    for i := 0;i<3;i++{ 
     fmt.Println(sample) 
    } 
} 

上面的代碼只是打印一個map [string]字符串三次。打印時,爲什麼Go的地圖迭代順序有所不同?

我期待它一個固定的輸出,但它顯示爲以下幾點:

map[key3:value3 key2:value2 key1:value1] 
map[key1:value1 key3:value3 key2:value2] 
map[key2:value2 key1:value1 key3:value3] 

它改變!

而在蟒蛇:

#!/bin/env python 
#encoding=utf8 

sample = { 
    "key1":"value1", 
    "key2":"value2", 
    "key3":"value3", 
} 
for i in range(3): 
    print sample 

輸出:

{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'} 
{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'} 
{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}` 
+1

原則上,地圖上的順序不保證,甚至不包括Python的順序,所以在打印地圖內容時確實不應該期待固定的輸出。這可能是由於一些內部實現細節。有趣的問題,雖然。 –

+0

@GiulioPiancastelli - 如果有人在第一次發佈Python 3.6之後出現(比如我現在):在python 3.6+關鍵字參數和dicts中,尊重插入順序(在參考C實現中開始) - 所以可以保留蛋糕並吃掉它;-)以前的python實現中的固定順序只是半固定的(在python v2中,根據插入順序,具有散列衝突的鍵的放置方式不同)... – Dilettant

回答

14

你不能指望在其中,你會拿到鑰匙的順序。語言規範says「映射是無序的元素組」,後面的「映射的迭代順序未指定,從一次迭代到下一次迭代不保證相同」。

3

Python不保證迭代的順序,但它確實保證該順序將保持穩定,只要你不修改就調用之間的詞典:

If items(), keys(), values(), iteritems(), iterkeys(), and itervalues() are 
called with no intervening modifications to the dictionary, the lists will 
directly correspond. 

Go不保證無論是。從你的例子看來,Go的順序可能是穩定的,只有起點不同,但沒有保證不依賴於它。

6

是的,它有所不同,甚至故意(先前未修改的地圖的迭代已穩定)。其目的是儘可能早地捕捉到某人錯誤地採取穩定的迭代保證的情況。此外,隨着地圖實現的額外自由度的出現,未來運行時間庫的這部分可能會有更多的優化。

相關問題