为什么Go的地图迭代顺序在打印时会有所不同?

时间:2012-12-06 13:50:57

标签: python map go

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]字符串三次。

我希望它是一个固定的输出,但它显示如下:

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

变化多了!

在python中:

#!/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'}`

4 个答案:

答案 0 :(得分:15)

您不能依赖获取密钥的顺序。语言规范says“地图是无序的元素组”,后来“未指定地图上的迭代顺序,并且不保证从一次迭代到下一次迭代是相同的。”

答案 1 :(得分:6)

是的,它变化甚至是故意的(未经修改的地图的迭代之前一直稳定)。目的是尽可能早地捕获有人错误地假设稳定迭代保证的情况。此外,随着地图实现的自由增加,未来可能会对运行时库的那部分进行更多优化。

答案 2 :(得分: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中的顺序可能是稳定的,只有起点变化,但没有保证不依赖它。

答案 3 :(得分:0)

据我所知,你不应该依赖地图迭代器的顺序,因为它没有逻辑顺序。

除此之外,我认为Go的地图迭代实现是故意随机的(http://nathanleclaire.com/blog/2014/04/27/a-surprising-feature-of-golang-that-colored-me-impressed/http://www.confreaks.com/videos/3419-gophercon2014-opening-day-keynote),这是为了阻止人们在代码中依赖它。

我希望有所帮助。