英文:
Are there any go libraries that provide associative array capability?
问题
我正在寻找与Python中的“dictionary”类似的Go语言功能,以便简化一些Python代码的转换。
编辑:对于这个去重应用程序,Maps(映射)效果很好。我能够使用一个带有16字节字符串索引的映射,将130万个重复项压缩为25万个唯一项,仅用几秒钟的时间。与此相关的映射代码很简单,所以我在下面包含了它。值得注意的是,预先分配包含130万个元素的映射只能提高几个百分点的速度:
var m = make(map[string]int, 1300000) // 初始化空间为130万个元素的映射
ct, ok := m[ax_hash]
if ok {
m[ax_hash] = ct + 1
} else {
m[ax_hash] = 1
}
英文:
I'm looking for a go language capability similar to the "dictionary" in python to facilitate the conversion of some python code.
EDIT: Maps worked quite well for this de-dupe application. I was able to condense 1.3e6 duplicated items down to 2.5e5 unique items using a map with a 16 byte string index in just a few seconds. The map-related code was simple so I've included it below. Worth noting that pre-allocation of map with 1.3e6 elements sped it up by only a few percent:
var m = make(map[string]int, 1300000) // map with initial space for 1.3e6 elements
ct, ok := m[ax_hash]
if ok {
m[ax_hash] = ct + 1
} else {
m[ax_hash] = 1
}
答案1
得分: 29
稍微详细解释一下已经给出的答案:
Go语言中的map是一种有类型的哈希映射数据结构。map的类型签名形式为map[keyType]valueType
,其中keyType
和valueType
分别是键和值的类型。
要初始化一个map,必须使用make
函数:
m := make(map[string]int)
未初始化的map等于nil
,如果读取或写入会在运行时引发panic。
存储值的语法与数组或切片的存储方式非常相似:
m["Alice"] = 21
m["Bob"] = 17
类似地,从map中检索值的方式如下:
a := m["Alice"]
b := m["Bob"]
您可以使用range
关键字在for
循环中迭代map:
for k, v := range m {
fmt.Println(k, v)
}
这段代码将打印:
Alice 21
Bob 17
对于不在map中的键的值,将返回值类型的零值:
c := m["Charlie"]
// c == 0
通过从map中读取多个值,您可以测试键是否存在。第二个值将是一个布尔值,指示键是否存在:
a, ok := m["Alice"]
// a == 21, ok == true
c, ok := m["Charlie"]
// c == 0, ok == false
要从map中删除键/值条目,只需将其反转并将false
赋值为第二个值:
m["Bob"] = 0, false
b, ok := m["Bob"]
// b == 0, ok == false
您可以使用空接口类型interface{}
在map中存储任意类型的值:
n := make(map[string]interface{})
n["One"] = 1
n["Two"] = "Two"
唯一的限制是在检索这些值时,必须执行类型断言以以原始形式使用它们:
a := n["One"].(int)
b := n["Two"].(string)
您可以使用类型开关来确定您提取的值的类型,并适当处理它们:
for k, v := range n {
switch u := v.(type) {
case int:
fmt.Printf("Key %q is an int with the value %v.\n", k, u)
case string:
fmt.Printf("Key %q is a string with the value %q.\n", k, u)
}
}
在每个case
块中,u
将是case
语句中指定的类型;不需要显式的类型断言。
这段代码将打印:
Key "One" is an int with the value 1.
Key "Two" is a string with the value "Two".
键可以是任何定义了相等运算符的类型,例如整数、浮点数、字符串和指针。接口类型也可以使用,只要底层类型支持相等性。(结构体、数组和切片不能用作map的键,因为这些类型上没有定义相等性。)
例如,map o
可以接受上述任何类型的键:
o := make(map[interface{}]int)
o[1] = 1
o["Two"] = 2
这就是关于map的简要介绍。
英文:
To expand a little on answers already given:
A Go map is a typed hash map data structure. A map's type signature is of the form map[keyType]valueType
where keyType
and valueType
are the types of the keys and values respectively.
To initialize a map, you must use the make
function:
m := make(map[string]int)
An uninitialized map is equal to nil
, and if read from or written a panic will occur at runtime.
The syntax for storing values is much the same as doing so with arrays or slices:
m["Alice"] = 21
m["Bob"] = 17
Similarly, retrieving values from a map is done like so:
a := m["Alice"]
b := m["Bob"]
You can use the range
keyword to iterate over a map with a for
loop:
for k, v := range m {
fmt.Println(k, v)
}
This code will print:
Alice 21
Bob 17
Retrieving a value for a key that is not in the map will return the value type's zero value:
c := m["Charlie"]
// c == 0
By reading multiple values from a map, you can test for a key's presence. The second value will be a boolean indicating the key's presence:
a, ok := m["Alice"]
// a == 21, ok == true
c, ok := m["Charlie"]
// c == 0, ok == false
To remove a key/value entry from a map, you flip it around and assign false
as the second value:
m["Bob"] = 0, false
b, ok := m["Bob"]
// b == 0, ok == false
You can store arbitrary types in a map by using the empty interface type interface{}
:
n := make(map[string]interface{})
n["One"] = 1
n["Two"] = "Two"
The only proviso is that when retrieving those values you must perform a type assertion to use them in their original form:
a := n["One"].(int)
b := n["Two"].(string)
You can use a type switch to determine the types of the values you're pulling out, and deal with them appropriately:
for k, v := range n {
switch u := v.(type) {
case int:
fmt.Printf("Key %q is an int with the value %v.\n", k, u)
case string:
fmt.Printf("Key %q is a string with the value %q.\n", k, u)
}
}
Inside each of those case
blocks, u
will be of the type specified in the case
statement; no explicit type assertion is necessary.
This code will print:
Key "One" is an int with the value 1.
Key "Two" is a string with the value "Two".
The key can be of any type for which the equality operator is defined, such as integers, floats, strings, and pointers. Interface types can also be used, as long as the underlying type supports equality. (Structs, arrays and slices cannot be used as map keys, because equality is not defined on those types.)
For example, the map o
can take keys of any of the above types:
o := make(map[interface{}]int)
o[1] = 1
o["Two"] = 2
And that's maps in a nutshell.
答案2
得分: 10
地图类型。http://golang.org/doc/effective_go.html#maps
与Python不同的是,键必须有类型,所以不能混合使用数字和字符串键(出于某种原因,我忘记了你可以这样做),但它们非常容易使用。
dict := make(map[string]string)
dict["user"] = "so_user"
dict["pass"] = "l33t_pass1"
英文:
The map type. http://golang.org/doc/effective_go.html#maps
There is some difference from python in that the keys have to be typed, <strike>so you can't mix numeric and string keys</strike> (for some reason I forgot you can), but they're pretty easy to use.
dict := make(map[string]string)
dict["user"] = "so_user"
dict["pass"] = "l33t_pass1"
答案3
得分: 0
你可能正在寻找一个map。
英文:
You're probably looking for a map.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论