字典是一种数据结构,用于存储一系列无序的键值对。

字典是基于键来存储值。字典功能强大的地方是能够基于键快速检索数据。

键就像索引一样,指向与键关联的值。

1.内部实现

字典是一个集合,可以使用类似处理数组和切片的方式迭代字典中的元素。

但字典是无序的集合,意味着没有办法预测键值对被返回的顺序。

即使使用同样的顺序保存键值对,每次迭代字典的时候顺序也可能不一样。

无序的原因是字典使用了散列表。

字典的散列表包含一组桶。在存储、删除或者查找键值对的时候,所有操作都要先选择一个桶。

把操作字典时指定的键传给字典的散列函数,就能选中对应的桶。

这个散列函数的目的是生成一个索引,这个索引最终将键值对分布到所有可用的桶里。

随着字典存储的增加,索引分布越均匀,访问键值对的速度就越快。

如果你在字典里存储了10000个元素,你不希望每次查找都要访问10000个键值对才能找到需要的元素,你希望查找键值对的次数越少越好。

对于有10000个元素的字典,每次查找都只需要查找8个键值对才是一个分布得比较好得字典。

字典通过合理数量的桶来平衡键值对得分布。

键会转化为一个数值(散列值)。这个数值落在字典已有桶的序号范围内表示一个可用于存储的桶的序号。

之后这个数值就被用于选择桶,用于存储或者查找指定的键值对。

对Go语言的字典来说,生成的散列键的一部分,具体来说是低位(LOB)被用来选择桶。

字典使用两个数据结构来存储数据。第一个数据结构是一个数组,内部存储的是用于选择桶的散列键的高八位值,

这个数值就被用于选择桶,用于存储或者查找指定的键值对。

第二个数据结构是一个字节数组,用于存储键值对。该字节数组先依次存储了这个桶里所有的键,之后依次存储了这个桶里所有的值。

实现这种键值对的存储方式目的在于减少每个桶所需的内存。

2.创建和初始化

 (1)使用make声明字典

Go语言中有很多中方法可以创建并初始化字典,可以使用内置的make函数,也可以使用字典字面量。

//创建一个字典,键的类型是string,值得类型是int
dict := make(map[string]int) //创建一个字典,键和值得类型都是string
//使用两个键值对初始化字典
dict := map[string]string{"name":"kebi", "sex":"boy"}

(2)使用字典字面量声明空字典

创建字典时更常用得方法是使用字典字面量。字典的初始长度会根据初始化时指定得键值对的数量来确定。

字典的键可以是任何值。这个值的类型可以是内置的类型,也可以是结构类型,只要这个值可以使用==运算符做比较。

切片、函数以及包含切片的结构类型这些类型由于具有引用语义,不能作为字典的键,使用这些键会造成编译错误。

dict := map[[]string]string{}  //invalid map key type []string

(3)声明一个存储字符串切片的字典

没有任何理由阻止用户使用切片作为字典的值。

//创建一个字典,使用字符串切片作为值。
dict := map[int][]string{}

  

3.使用字典

 (1)为字典赋值

键值对赋值给字典,是通过指定适当类型的键并给这个件赋予一个值来完成的。

//创建一个空字典,用来存储颜色以及颜色对应的十六进制代码
colors := map[string]string{} //将Red的代码加入到字典
colors["Red"] = "#da1337"

(2)对nil字典赋值时的语言运行时错误

可通过声明一个未初始化的字典来创建一个值为nil的字典。

nil字典不能用于存储键值对,否则,会产生一个语言运行错误

//通过声明字典创建一个nil字典
var colors map[string]string //将red的代码加入到字典
colors["red"] = "#da1337" //assignment to entry in nil map

(3)从字典获取值并判断键是否存在

测试字典里是否存在某个键是字典的一个重要操作。

这样操作允许用户写一些逻辑来确定是否完成某个操作或者是否在字典里缓存了一个特定数据。

这样操作也可以用来比较两个字典,来确定那个键值对互相匹配,那些键值对不匹配。

从字典取值时有两个选择。第一个选择是,可以同时获得值,以及一个表示这个键是否存在的标志。

//获取键blue对应的值
value, exists := colors["blue"] //这个键存在吗?
if exists {
fmt.PrintLn(value)
}

(4)从字典获取值,并通过该值判断键是否存在

另一个选择是,只返回键对应的值,然后判断这个值是不是零值来确定键是否存在。

//获取键Blue对应得值
value := colors["blue"] //这个键存在吗?
if value != " " {
fmt.PrintLn(value)
} 

在Go语言里,通过键来索引字典时,即便这个键不存在也总会返回一个值。

在这种情况下,返回得是该值对应得类型的零值。

(5)使用range迭代字典

迭代字典里的所有值和迭代数组或切片一样,使用关键字range。

对字典来说,range返回的不是索引的值,而是键值对。

package main

import "fmt"

func main() {
//创建一个字典,存储颜色以及颜色对应的十六进制代码
colors := map[string]string{
"red": "#34567",
"blue": "#6789",
"pink": "#drtuft",
"yellow": "#df67",
}
//显式所有颜色
for key, value := range colors {
fmt.Printf("Key: %s, value: %s\n", key, value)
}
} /*
结果
Key: red, value: #34567
Key: blue, value: #6789
Key: pink, value: #drtuft
Key: yellow, value: #df67
*/

(6)从字典中删除一项

如果想要把一个键值从字典里删除,就使用内置的delete函数。

//删除键为red的键值对
delete(colors, "red)

  

4.在函数间传递字典

在函数键传递字典并不会制造出该字典的一个副本。

实际上,当传递一个字典给一个函数,并对这个函数做出修改时,所有对这个字典的引用都会察觉到这个修改。

package main

import "fmt"

func recoveColor(colors map[string]string, key string) {
delete(colors, key)
} func main() {
//创建一个字典,存储颜色以及颜色对应的十六进制代码
colors := map[string]string{
"red": "#34567",
"blue": "#6789",
"pink": "#drtuft",
"yellow": "#df67",
}
//显式所有颜色
for key, value := range colors {
fmt.Printf("Key: %s, value: %s\n", key, value)
} //调用函数移除指定的键
recoveColor(colors, "red") //显式所有颜色
fmt.Println(" ")
for key, value := range colors {
fmt.Printf("Key: %s, value: %s\n", key, value)
}
}
/*
直接修改原字典
Key: red, value: #34567
Key: blue, value: #6789
Key: pink, value: #drtuft
Key: yellow, value: #df67 Key: yellow, value: #df67
Key: blue, value: #6789
Key: pink, value: #drtuft
*/

  

go——字典(二)的更多相关文章

  1. python中的列表和字典(二)

    三. 字典以及相关使用 1. 字典的定义 dict{} 2. 字典特征:字典是无序的,key-value键值对形式,key值不重复 3. 字典的赋值:dictA = {keyA: valueA, ke ...

  2. python之字典二 内置方法总结

    Python字典包含了以下内置方法: clear()函数用于删除字典内所有元素 dict1 = {, 'Class': 'First'} print('the start len %d' % len( ...

  3. python 全栈开发,Day7(元组转换,列表以及字典的坑,集合,关系测试,深浅copy,编码补充)

    一.元组转换 数字 tu = (1) tu1 = (1,) print(tu,type(tu)) print(tu1,type(tu1)) 执行输出: 1 <class 'int'>(1, ...

  4. python简说(二十四)发送网络请求

    一.get,post请求import requestsurl='http://127.0.0.1:8999/api/upload'# data = {'username':'testuser1','p ...

  5. 树-二叉搜索树-AVL树

    树-二叉搜索树-AVL树 树 树的基本概念 节点的度:节点的儿子数 树的度:Max{节点的度} 节点的高度:节点到各叶节点的最大路径长度 树的高度:根节点的高度 节点的深度(层数):根节点到该节点的路 ...

  6. python新手之字典增删改查

    一.字典的定义 city_list = { 'beijin':"北京",'shanghai':"上海" } print(city_list) 二.字典添加一个元 ...

  7. Django框架(二十二)-- Django rest_framework-解析器

    一.解析器的作用 根据请求头 content-type 选择对应的解析器对请求体内容进行处理,将传过来的数据解析成字典 二.使用解析器 1.局部使用 在视图类中重定义parser_classes即可, ...

  8. 常用内置模块(二)--logging、hashlib、shelve、xml、configparser

    一.logging模块 1.logging作用 1. 控制日志级别  2. 控制日志格式  3. 控制输出的目标为文件 2.日志级别 1 logging.debug( 2 logging.info( ...

  9. Django框架(二十三)—— Django rest_framework-解析器

    解析器 一.解析器的作用 根据请求头 content-type 选择对应的解析器对请求体内容进行处理,将传过来的数据解析成字典 二.使用解析器 1.局部使用 在视图类中重定义parser_classe ...

  10. python字典和列表使用

    一.字典中健值为列表或字典 1 a.setdefault(key,[]).append(b)--键值是列表 2 a.setdefault(key,{}).append(b)--键值是字典 二.键值为列 ...

随机推荐

  1. java+lucene中文分词,来看看百度究竟是怎么找到你想要的(十分重要,楼主幸苦之作)

    我想只要是学过数据库的孩纸,不管是mysql,还是sqlsever,一提到查找,本能的想到的便是like关键字,其实去转盘网(分类模式)之前也是采用这种算法,但我可以告诉大家一个很不幸的事情,like ...

  2. SQL Server DTS向导,字段转换出现202和200错误

    当使用SQL Server 2012的DTS向导(Import and Export Data/导入导出数据)时,会出现如下问题: 当来源数据直接使用表的时候,没有任何问题 但如果来源数据是查询时,就 ...

  3. hdu6070 Dirt Ratio 二分+线段树

    /** 题目:hdu6070 Dirt Ratio 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意:给定n个数,求1.0*x/y最小是多少.x ...

  4. JS 怎么刷新当前页面

    reload 方法,该方法强迫浏览器刷新当前页面. 语法:location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当前页 ...

  5. 第二百一十九节,jQuery EasyUI,DateTimeBox(日期时间输入框)组件

    jQuery EasyUI,DateTimeBox(日期时间输入框)组件 学习要点: 1.加载方式 2.属性列表 3.方法列表 本节课重点了解 EasyUI 中 DateTimeBox(日期时间输入框 ...

  6. js用计时器加载大量dom

    改进前: <table><tbody></tbody></table> var tbody=document.getElementsByTagName( ...

  7. 从零开始开发一个vue组件打包并发布到npm (把vue组件打包成一个可以直接引用的js文件)

    自己写的组件 有的也挺好的,为了方便以后用自己再用或者给别人用,把组件打包发布到npm是最好不过了,本次打包支持 支持正常的组件调用方式,也支持Vue.use, 也可以直接引用打包好的js文件, 配合 ...

  8. kafka 并发数配置过程中踩到的坑 InstanceAlreadyExistsException

    ] WARN org.apache.kafka.common.utils.AppInfoParser- Error registering AppInfo mbean javax.management ...

  9. BF算法 + KMP算法

    准备: 字符串比大小:比的就是字符串里每个字符的ASCII码的大小.(其实这样的比较没有多大的意义,我们关心的是字符串是否相等,即匹配等) 字符串的存储结构:同线性表(顺序存储+链式存储) 顺序存储结 ...

  10. 【BZOJ4540】[Hnoi2016]序列 莫队算法+单调栈

    [BZOJ4540][Hnoi2016]序列 Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,a ...