[Python] Python数据类型(四)映射类型中的字典类型

映射类型是一类可迭代的键-值数据项的组合,提供了存取数据项及其键和值的方法,在python3中,支持两种无序的映射类型:内置的dict和标准库中的collections.defaultdict类型。
在python3.1后,还引入了一种有序的映射类型:collections.OrderedDict.

特点:
  • 1.只有可哈希运算的对象可用于映射类型中的键,因此,内置的固定的数据类型都可以用作映射类型中的键(内置固定的类型都可进行哈希运算),目前接触到的固定数据类型有:int、float、complex、bool、str、tuple、frozenset
  • 2.每个键相关联的值可以是任意对象;
  • 3.映射类型也是可迭代的(iterable)。
  • 4.映射类型可以使用比较操作符进行比较,可以使用成员关系符in/not in和内置len()函数。

1.dict(字典)

dict数据类型是一种无序的、可变的组合数据类型,其中包含0-n个键值对,键是指向可哈希运算的对象的引用,值可以指向任意对象的引用。由于键是可哈希运算的对象引用,因此保证了键的唯一性;由于dict是可变的,因此可以对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进行操作了。

操作dict

1.迭代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}

2.collections.defaultdict(默认字典)

defaultdict是dict的子类,它支持dict的所有的操作和方法。和dict的不同之处在于,如果dict中不包含某一个键,则通过dict[x]取值时出现KeyError异常,但是如果是defaultdict,则会创建一个新的项,键为该键,值为默认值。

创建collections.defaultdict

创建collections.defaultdict时,通过collections.defaultdict(),根据参数可以有两种方式进行创建:

* 1.使用参数类型来创建:
>>> 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,[],”

* 2.使用函数名来创建:
>>> 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()方法了。

你可能感兴趣的:(Python)