2012-12-06 31 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

是的,它有所不同,甚至故意(先前未修改的地图的迭代已稳定)。其目的是尽可能早地捕捉到某人错误地采取稳定的迭代保证的情况。此外,随着地图实现的额外自由度的出现,未来运行时间库的这部分可能会有更多的优化。

相关问题