Я ищу способ языка, похожий на "словарь" в python, чтобы облегчить преобразование некоторого кода на Python.
EDIT: Карты работали достаточно хорошо для этого де-dupe приложения. Я смог сконденсировать 1.3e6 дублированные элементы до 2.5e5 уникальных элементов, используя карту с индексом строки из 16 байтов всего за несколько секунд. Код, связанный с картой, был простым, поэтому я включил его ниже. Стоит отметить, что предварительное выделение карты с элементами 1.3e6 ускорило ее всего на несколько процентов:
Ответ 2
Чтобы немного рассказать о полученных ответах:
A Go map - типизированная структура данных хэш-карты. Подпись типа карты имеет вид map[keyType]valueType
, где keyType
и valueType
- типы ключей и значений соответственно.
Чтобы инициализировать карту, вы должны использовать функцию make
:
m := make(map[string]int)
Неинициализированное отображение равно nil
, и если во время выполнения будет прочитана или записана паника.
Синтаксис для хранения значений почти такой же, как при использовании массивов или фрагментов:
m["Alice"] = 21
m["Bob"] = 17
Аналогично, извлечение значений из карты выполняется следующим образом:
a := m["Alice"]
b := m["Bob"]
Вы можете использовать ключевое слово range
для перебора по карте с циклом for
:
for k, v := range m {
fmt.Println(k, v)
}
Этот код напечатает:
Alice 21
Bob 17
Извлечение значения для ключа, который не находится на карте, вернет значение типа нулевого значения:
c := m["Charlie"]
// c == 0
Читая несколько значений с карты, вы можете проверить наличие ключа. Второе значение будет логическим, указывающим наличие ключа:
a, ok := m["Alice"]
// a == 21, ok == true
c, ok := m["Charlie"]
// c == 0, ok == false
Чтобы удалить запись ключа/значения с карты, вы переверните ее и назначьте false
в качестве второго значения:
m["Bob"] = 0, false
b, ok := m["Bob"]
// b == 0, ok == false
Вы можете хранить произвольные типы на карте, используя пустой тип интерфейса interface{}
:
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".
Ключ может быть любого типа, для которого определен оператор равенства, например целые числа, поплавки, строки и указатели. Также можно использовать типы интерфейсов, если базовый тип поддерживает равенство. (Структуры, массивы и срезы не могут использоваться в качестве ключей карты, потому что для этих типов не определено равенство.)
Например, карта o
может принимать ключи любого из следующих типов:
o := make(map[interface{}]int)
o[1] = 1
o["Two"] = 2
И это отображает в двух словах.