python,golang的几种数据集合类型(二)
2.字典
1) python
python中 字典是以‘{}’来表示,数组以'[]'来表示,元组tuple以'()'来表示。
a) 初始化
以key:value格式初始化就行。
1 >>> a={1:2,"2":3,"3":"4"} 2 >>> a 3 {1: 2, '3': '4', '2': 3}
key,value的类型,在一个字典里面可以有多种(注:key不能是数组(list),因为key不可修改,可以是元组(tuple))。如果在初始化的时候,写了同样的key,那么后写的key会覆盖前面的。
1 >>> b={1:"aaa",1:"bbb"} 2 >>> b 3 {1: 'bbb'}
b) 访问元素
直接通过[ ]来取,有点像数组(list),不过中括号中间是key,不是下标。
1 >>> a["2"] 2 3 3 >>> a[1] 4 2 5 >>> a[2] 6 Traceback (most recent call last): 7 File "<stdin>", line 1, in <module> 8 KeyError: 2
如果没有这个key会报错。所以一般要做好判断:
1 >>> a={1:"aaa",2:"bbb",3:"ccc"} 2 >>> a.has_key(3) # 字典的自带方法 has_key 3 True 4 >>> a.has_key(4) 5 False 6 >>> 3 in a # key in dict的方法,和数组的 val in list 类似。 7 True 8 >>> 4 in a 9 False
遍历:
1 for k in a: 2 print "k:",k 3 4 for (k,v) in a.items(): 5 print "k:",k,",v:",v 6 7 for k,v in a.iteritems(): 8 print "k:",k,",v:",v
其中第一种方式的k是key值,而不是value值;数组(list)这样遍历返回的是值,而不是下标(话说返回下标也没啥意义啊。。O__O "…)。这里需要留意下。
c) 修改元素
直接赋值。值可以修改为任何类型。注意如果在遍历中修改值。比如上面例子中,赋值 v=xxx是不能修改字典本身的。
1 a[1] = "2" 2 a[1] = 22 3 a[1] = {"k1":"v1","k2":"v2"}
d) 插入元素
同修改元素的操作一样。直接赋值,key不存在就是插入新的元素。
e) 删除元素
1.可以使用del关键字。删除字典中的元素(同样,如果key不存在,以a[key]取值的方式也会报异常),或者删除字典本身。这个类似数组中的操作。
1 >>> a={1:"aaa",2:"bbb"} 2 >>> del a[1] #删除字典元素 3 >>> a 4 {2: 'bbb'} 5 6 >>> del a #删除字典 7 >>> a 8 Traceback (most recent call last): 9 File "<stdin>", line 1, in <module> 10 NameError: name 'a' is not defined
2.使用字典自带的方法
1 >>> a={1:"aaa",2:"bbb"} 2 >>> a.pop(1) #使用pop(key)方法。但如果key不存在,则报异常。 3 'aaa' 4 >>> a 5 {2: 'bbb'} 6 7 >>> a.pop(3,"") #可以使用带default参数(这里是空字符串"")的pop方法,这样若key 3不存在,则返回这个default值""。 8 '' 9 10 11 >>> a.clear() #可以使用clear(),清空整个字典(不同于del,这里字典本身还在)。 12 >>> a 13 {}
2) golang
a) 初始化
map的key 可以是任意可以用 == 或者!= 操作符比较的类型,比如 string、int、float。所以数组、切片和结构体不能作为 key (注:含有数组切片的结构体不能作为 key,只包含内建类型的 struct 是可以作为 key 的),但是指针和接口类型可以。value 可以是任意类型的,包括函数等接口类型。
出于性能的考虑,对于大的 map 或者会快速扩张的 map,即使只是大概知道容量,也最好先标明其容量capacity。
var a map[int]string // 刚定义完的a,值是nil,直接引用会抛异常 b := make(map[int]string) // 初始化完的数组,可以使用了 a = b // 通过赋值,可以完成a的初始化 var a map[int]string = map[int]string{123:"abc",456:"aaa"} // 完成初始化 a := map[int]string{123:"abc",456:"aaa"} // 完成初始化
a := make(map[int]string, 100) // 初始化数组,并且给出初始容量
b) 访问元素
直接通过key使用[]取值(尽管已经很快,但是还是比数组和切片的[]取值慢很多)。
value := map1[key] // 如果key不存在,会返回value的零值(即value是string就是“”,value是指针或接口就是nil等等)。这点和python不一样。
value, ok := map1[key] // 可以依据ok判断key是否存在,true即存在;false不存在,此时value给出其零值。
遍历:
map的底层是哈希表实现的,所以map不会依据key来排序。
map1 := map[int]string{123: "aaa", 234: "bbb", 345: "ccc"} for key := range map1 { //这里和python类似 ... } for key, value := range map1 { ... } for key, _ := range map1 { ... } for _, value := range map1 { ... }
c) 修改元素
使用[]直接赋值。一般来说,把值取出来再操作,是达不到修改map本身的目的的。这和python一样。
for key, value := range map1 { map1[key] = "ddd" // 会修改map1中的值 value = "ddd" // 这里只是修改的拷贝出来的value,不能修改map1里的值 }
d) 插入元素
同修改元素的操作一样。直接赋值,key不存在就是插入新的元素。
e) 删除元素
delete(map1, key1) // 即使key1不存在,也不会报错。这和python的del a[key]会报错是不一样的。