映射类型是一类可迭代的键-值数据项的组合,提供了存取数据项及其键和值的方法,在python3中,支持两种无序的映射类型:内置的dict和标准库中的collections.defaultdict类型。
在python3.1后,还引入了一种有序的映射类型:collections.OrderedDict.
int、float、complex、bool、str、tuple、frozenset
;in/not in
和内置len()
函数。dict数据类型是一种无序的、可变的组合数据类型,其中包含0-n个键值对,键是指向可哈希运算的对象的引用,值可以指向任意对象的引用。由于键是可哈希运算的对象引用,因此保证了键的唯一性;由于dict是可变的,因此可以对dict进行数据项的添加和移除操作;由于dict是无序的,因此没有索引,也不能使用分片操作符进行操作。
1.dict()
可以作为一个函数调用,此时创建一个空dict:
>>> dict()
{}
>>>
dict()
中传入一个映射类型的参数时,将返回以该参数为基础的字典,如:
>>> d1 = {"key1":"value1","key2":"value2"}
>>> dict(d1)
{'key1': 'value1', 'key2': 'value2'}
>>>
dict()
还可以接受序列类型的参数,但是前提是序列中的每一个数据项本身是一个包含两个对象的序列,第一个用作键,第二个用作值,如:
>>> d1 = dict((("k1","v1"),("k2","v2"))) #使用元组创建
>>> d1
{'k1': 'v1', 'k2': 'v2'}
>>>
>>> d1 = dict([("k1","v1"),("k2","v2")]) #使用序列创建
>>> d1
{'k1': 'v1', 'k2': 'v2'}
>>>
dict()
中还可以关键字参数进行创建,其中键作为关键字,值作为关键字的值,如:
>>> dict(id=1,name="zhangsan",age=23)
{'id': 1, 'name': 'zhangsan', 'age': 23}
>>>
注意:关键字必须为有效的python标识符
2.使用花括号创建dict,空{}会创建一个空的dict,非空dict由多个项组成,每一项由逗号分隔,其中每一项都使用K:V
的形式创建,如:
>>> dict2 = {"name":"kobe","age":33,"num":24}
>>> dict2
{'name': 'kobe', 'age': 33, 'num': 24}
>>>
3.使用字典内涵创建字典(单独列出)
操作符:
[]
用于存取dict中的某一个单值,如:
>>> d =dict(k1="value1",k2="value2")
>>> d["k1"]
'value1'
>>>
=
:用于添加或替换dict中某一项,如:
>>> d = dict()
>>> d["k1"]="V1"
>>> d
{'k1': 'V1'}
>>>
如果存在键k1,则使用“V1”替换原来“k1”的值。
注意:dict是无序的,不能使用分片操作符[],但这里的[]并非分片操作符。
del语句
:删除某一项,如:
>>> d
{'k1': 'value1', 'k2': 'value2'}
>>> del d["k1"]
>>> d
{'k2': 'value2'}
>>>
如果存在指定的键,则移除,如果不存在,则会出现KeyError
异常。
in/not in
:通过键进行成员关系判断,如:
>>> "k2" in d
True
>>> "value2" in d #通过键进行判断,而不是值
False
>>>
方法:
d.clear()
:移除dict中所有项;
d.copy()
:返回d的浅拷贝:
>>> d = dict(id = 1,name = "zhangsan",age = 23,gendor = "男")
>>> d2 = d.copy()
>>> d2
{'id': 1, 'name': 'zhangsan', 'age': 23, 'gendor': '男'}
>>>
d.fromkeys(s,v)
:返回一个dict,该dict的键为序列s中的项,值为None或者v,参数v可选:
>>> d.fromkeys(["k1","k2","k3"],0)
{'k1': 0, 'k2': 0, 'k3': 0}
>>>
d.get(k)
:通过给定的键返回对应的值,如果不存在就返回None:
>>> d.get("name")
'zhangsan'
>>>
d.get(k,v)
:通过给定的键返回对应的值,如果不存在就返回v.
d.items()
:返回d中所有键值对的字典视图;
>>> d.items()
dict_items([('id', 1), ('name', 'zhangsan'), ('age', 23), ('gendor', '男')])
>>>
字典视图,是一个只读的并且可迭代的itreable对象,存放了字典的键和值。
d.keys()
:返回d中所有键的视图
>>> d.keys()
dict_keys(['id', 'name', 'age', 'gendor'])
>>>
d.pop(k)
:返回并移除d中的k和k对应的值,如果不存在k,出现KeyError异常:
d.popitem()
:返回并移除d中任意一个键值对,如果d为空,则产生KeyError异常:
>>> d.pop("age")
23
>>> d.popitem()
('gendor', '男')
>>> d.items()
dict_items([('id', 1), ('name', 'zhangsan')])
>>>
d.setdefalut(k,v)
:返回d中k的值,如果不存在,就在d中插入k-v:
>>> d.setdefault("gender","男")
'男'
>>> d.items()
{'id': 1, 'name': 'zhangsan', 'gender': '男'}
>>>
d.update(i)
:将i中每个尚未包含在d中的k-v添加到d中,或者将d中包含了i中k-v的键,使用i中的v进行替换,但是i中每一项只能为2个长度,否则出现ValueError异常,也可以使用关键字参数:
>>> d.update([("weight"),(23)])
Traceback (most recent call last):
File "" , line 1, in
d.update([("weight"),(23)])
ValueError: dictionary update sequence element #0 has length 6; 2 is required
>>>
>>> d.update(["kv"]) #ok
>>> d
{'id': 1, 'name': 'zhangsan', 'gender': '男', 'k': 'v'}
>>>
>>> d.update(gender = "男") #关键字参数
>>> d
{'id': 1, 'name': 'zhangsan', 'age': 23, 'gender': '男'}
>>>
d.values()
:返回d中所有值的视图:
>>> d.values()
dict_values([1, 'zhangsan', '男'])
>>>
掌握这些基本方法后,就可以对dict进行操作了。
可以使用d.items(),d.values(),d.keys()迭代dict,如:
>>> for item in d.items(): #使用itmes()迭代
print(item[0],item[1])
id 1
name zhangsan
gender 男
k v
>>>
>>> for key in d.keys(): #使用keys()迭代
print(key,d.get(key))
id 1
name zhangsan
gender 男
k v
>>>
>>> for value in d.values(): #使用values()迭代
print(value)
1
zhangsan
男
v
>>>
也可以直接使用dict来遍历,等同于使用d.keys(),如:
>>> for key in d:
print(key)
id
name
gender
k
在使用dict.items(),dict.keys(),dict.vaules()
时,返回的是一个字典视图,字典视图也可以当做一个iterable,除此之外,字典视图还能支持一些类似集合的操作,如:
d1v & d2v
:返回d1和d2的交集;
d1v | d2v
:返回d1和d2的并集;
d1v - d2v
:返回包含在d1但不包含在d2中的数据项的集合
d1v ^ d2v
:返回d1和d2的对称差集,即交集之外数据项的集合;
>>> d1 = {}.fromkeys("ABCD",0)
{'A': 0, 'B': 0, 'C': 0, 'D': 0}
>>> d2 = {}.fromkeys("ABCDE",0)
{'A': 0, 'B': 0, 'C': 0, 'D': 0, 'E': 0}
1.dict的键是唯一的,因此可以用来存放排他性项的数,这里使用dict.get(k,v)
方法来统计一个str中各个字母出现的个数:
>>> s = "hi,my name is James,nice to meet you" #字符串
>>> d = {} #创建一个空dict字典
>>> for letter in s.lower(): #将str全部变为小写后进行遍历
d[letter]=d.get(letter,0)+1 #每次遍历的str作为K,将值+1
>>> for element in d:
print("the \"{0}\" occurs {1} times".format(element,d[element]))
the "h" occurs 1 times
the "i" occurs 3 times
the "," occurs 2 times
the "m" occurs 4 times
the "y" occurs 2 times
the " " occurs 6 times
the "n" occurs 2 times
the "a" occurs 2 times
the "e" occurs 5 times
the "s" occurs 2 times
the "j" occurs 1 times
the "c" occurs 1 times
the "t" occurs 2 times
the "o" occurs 2 times
the "u" occurs 1 times
>>>
在这个例子中,通过dict.get(K,V)
将遍历的字母和出现的次数分别作为键和值,如果第一次不存在,则d[letter]=get(letter,0)
使用默认值0,之后每次都会对letter+1。如果不使用dict.get(k,v)
,也可以按照如下方式进行:
>>> for letter in s.lower():
if letter not in d:
d[letter] = 0
d[letter]+=1
dict.get(k,v)
显然是更加巧妙。
在之前总结序列类型和集合类型时,为方便创建长的列表和集合,有了列表内涵和集合内涵的概念,同样的,python还提供了字典内涵这个语法用来创建非常长的字典,字典内涵是一个循环表达式,格式如下:
{keyexpression:valueexpression for key,value in iterable if condition}
defaultdict是dict的子类,它支持dict的所有的操作和方法。和dict的不同之处在于,如果dict中不包含某一个键,则通过dict[x]取值时出现KeyError异常,但是如果是defaultdict,则会创建一个新的项,键为该键,值为默认值。
创建collections.defaultdict时,通过collections.defaultdict()
,根据参数可以有两种方式进行创建:
>>> import collections
>>> cd1 = collections.defaultdict(int)
>>> cd2 = collections.defaultdict(list)
>>> cd3 = collections.defaultdict(str)
>>> cd1["x"]
0
>>> cd2["x"]
[]
>>> cd3["x"]
''
>>>
这里分别使用了int、list、str,他们的默认值分别为0,[],”
>>> def name():
return 'zhangsan'
>>> cd4 = collections.defaultdict(name)
>>> cd4["x"]
'zhangsan'
>>>
通过这种方式,可以使默认字典的默认值更加灵活。
需要注意的是,collections.defaultdict()
可以不传入参数或者传入None,但是如果这样,则不支持默认值,比如:
>>> cd5 = collections.defaultdict()
>>> cd5["x"]
Traceback (most recent call last):
File "" , line 1, in
cd5["x"]
KeyError: 'x'
>>>
有了collections.defaultdict
,可以代替dict中的get(k,v)
和setdefault()
方法了。