Python学习教程(四)——字典

来源:互联网 发布:moto z force网络参数 编辑:程序博客网 时间:2024/06/01 09:43

  字典是Python中唯一的内建映射类型。字典中的值没有特殊的顺序,但是都是存储在一个特定的键(key)下。键可以是数字、字符串、甚至是元组。

1. 字典的创建和使用

1.1. 字典的创建

  字典可以通过下列方式创建:

>>> phonebook = {'zhangsan':'415654','lisi':'46546','ylh':'46846'}>>> emptydic = {}

字典中的键必须是唯一的,如果不唯一,后面的会覆盖的前面的。

  也可以使用dict函数,通过其他映射(比如其他字典)或者(键值)对的序列建立字典。

>>> items = [('name','yangliehui'),('age',28)]>>> d = dict(items)>>> d{'age': 28, 'name': 'yangliehui'}>>> d['name']'yangliehui'

  也可以通过关键字参数创建字典。

>>> d = dict(name='yangliehui',age=28)>>> d{'age': 28, 'name': 'yangliehui'}

1.2. 字典的基本操作

  字典的基本行为在很多方面与序列类似:

  • len(d)返回d中项(键值对)的数量:
>>> items = {('name','yangliehui'),('age',28)}>>> d = dict(items)>>> d{'age': 28, 'name': 'yangliehui'}>>> len(d)2
  • d[k]返回关联到k上的值:
>>> d['age']28
  • d[k]=v 将值v关联到键k上:
>>> d['age'] = 30>>> d{'age': 30, 'name': 'yangliehui'}
  • del d[k] 删除键为k的项:
>>> del d['age']>>>>>> d{'name': 'yangliehui'}
  • k in d 检查d中是否含有键为k的项:
>>> d{'name': 'yangliehui'}>>> 'age' in dFalse>>> 'name' in dTrue

字典和列表的一些区别:

键类型:
可以是任意的不可变类型,比如:浮点型(实型)、整型、字符串或者元组;
自动添加:
即使键起初在字典中并不存在,也可以为它赋值,这样字典就会建立新的项。而对于列表,在不使用append方法或者其他类似操作的情况下,是不能将值关联到列表范围之外的索引上的。
>>> x = []>>> x[42] = 'Foobar'Traceback (most recent call last):  File "<stdin>", line 1, in <module>IndexError: list assignment index out of range>>> x = {}>>> x[42] = 'Foobar'>>> x{42: 'Foobar'}

首先,程序试图将字符串’Foobar’关联到一个空列表42号位置上,这显然不可能,因为这个位置不存在。但是我们可以将’Foobar’关联到空字典的键42上。

成员资格:
表达式 k in d (d为字典) 查找的是键而不是值。 表达式 v in l (l为列表)则用来查找的是值而不是索引。在字典中检查键的成员资格比在列表中检查值的成员资格更高效,数据结构的规模越大,两者的效率差距越明显。

字典的值可以还是一个字典:

>>> people = {... 'yangliehui' : {...     'phone' : '18710026xxx',...     'addr'  : 'beijing'...     },... 'zhangsan' : {...     'phone' : '13565487xxx',...     'addr'  : 'shanghai'...     }... }>>> people{'yangliehui': {'phone': '18710026xxx', 'addr': 'beijing'}, 'zhangsan': {'phone': '13565487xxx', 'addr': 'shanghai'}}

1.3. 字典的格式化字符串

  先看一个例子:

>>> phonebook = {'yanglh':'3384','zhangbh':'3404','gaoy':'3323'}>>> "yanglh's phone number is %(yanglh)s ." % phonebook"yanglh's phone number is 3384 ."

我们看到,可以使用字典格式化字符串。

1.4. 字典的方法

1.4.1. clear方法

  清除字典中所有的项。这个是一个原地操作,没有返回值,或者说返回值为None。

>>> d = {}>>> d['name'] = 'yangliehui'>>> d['age'] = 28>>> d{'age': 28, 'name': 'yangliehui'}>>> d_clear = d.clear()>>> d{}>>> print d_clearNone

1.4.2. copy方法

  返回一个具有相同键值对的新字典,但是该方法实现的浅复制(shallow copy),因为值本身是相同的,不是副本,就像Java中的对象,copy的是一个引用,指向的是同一个地址。

>>> x = {'username':'yangliehui' , 'machines':['foo','bar','baz']}>>> y = x.copy()>>> #此时x和y的值是一样的,下面我们对y值做一些操作>>> y['username'] = 'yanglh'>>> y['machines'].remove('bar')>>> #再看x和y的值分别是>>> x{'username': 'yangliehui', 'machines': ['foo', 'baz']}>>> y{'username': 'yanglh', 'machines': ['foo', 'baz']}

我们看到,当在副本y中替换值的时候,原始字典x不受影响。但是,如果修改了某个值(注意是原地修改,不是替换),原始字典也会改变。这就是浅复制的原因。解决这个问题的办法是使用深复制(deep copy)


copy 模块的deepcopy函数实现的深度复制(deep copy):

>>> from copy import deepcopy>>> x = {'username':'yangliehui' , 'machines':['foo','bar','baz']}>>> y = x.copy()>>> y_dc = deepcopy(x)>>> x['machines'].remove('bar');>>> y{'username': 'yangliehui', 'machines': ['foo', 'baz']}>>> y_dc{'username': 'yangliehui', 'machines': ['foo', 'bar', 'baz']}

上面的例子中,首先导入了copy模块的deepcopy方法;
定义了字典x,’machines’键对应的值是一个列表;
然后用浅复制(y)和深度复制(y_dc)别进行了复制操作;
随后我们原地修改原字典x中’machines’键对应的值;
最后我们看到结果,浅复制得到的y里面的’machines’键对应的值也变化了,说明浅复制时复制的只是一个值的引用,当原值改变后也会随着改变;而深度复制得到的y_dc没有受到原值修改的影响;

1.4.3. fromkeys方法

  fromkeys方法使用给定的键建立新的字典,每一个键都对应一个默认的值None。

>>> {}.fromkeys(['name','age']){'age': None, 'name': None}

上面的代码中首先是构造了一个空字典{},然后调用了fromkeys方法又建了一个新的字典,显得有些多余。所以我们还可以用下面的方法。

>>> dict.fromkeys(['name','age']){'age': None, 'name': None}

  上面这段代码使用了dict代替了原来的空字典。因为dict是所有字典的类型(关于类型和类的概念会在后面涉及到,这里我们只需要知道这种使用方式即可)。

  如果不想使用None作为默认值,也可以自己定义默认值,如下例子:

>>> dict.fromkeys(['name','age'],'UNKNOWN'){'age': 'UNKNOWN', 'name': 'UNKNOWN'}

上面的代码就是使用了fromkeys方法的第二个参数,实现了自定义默认值。

1.4.4. get方法

  get方法是一个访问字典项的方法,看一下下面的例子:

>>> d = {'name':'yangliehui','age':28}>>> d{'age': 28, 'name': 'yangliehui'}>>> print d['id']Traceback (most recent call last):  File "<stdin>", line 1, in <module>KeyError: 'id'>>> #################################...>>> print d.get('id');None

  看一下上面的例子,首先创建了一个字典,访问一个字典的项,我用了上面的两种方法,这两种方法我都访问的是一个不存在项,我们发现第一种方法报错了,而第二种用get的方法没有报错,当没有找到项时返回了None。所以,get是一种更为宽松的访问字典的方法
  假如我们在使用get时,当找不到对应的项时不想返回None,而是自定义一个值,get提供了对应的解决方案来替代“None”,看下面的代码:

>>> d = {'name':'yangliehui','age':28}>>> d.get('id','N/A')'N/A'

1.4.5. has_key方法

  用于检查字典中是否含有特定的键。表达式d.has_key(k)相当于表达式k in d
  注意:Python3.0中不包含该方法。

>>> d = {'name':'yangliehui','age':28}>>> d{'age': 28, 'name': 'yangliehui'}>>> d.has_key('name')True>>> d.has_key('id')False

1.4.6. items和iteritems方法

  这两个方法都是将字典中所有的项以列表的方式返回,列表中的每一个项都表示为(键,值)对应的形成。

>>> d = {'name':'yangliehui','age':28}>>> d.items()[('age', 28), ('name', 'yangliehui')]>>> ###################################...>>> it = d.iteritems()>>> it<dictionary-itemiterator object at 0x00000000025B6F98>>>> list(it)[('age', 28), ('name', 'yangliehui')]

  我们来看一下上面的代码,items方法直接返回了结果,而iteritems方法返回的是一个迭代器:<dictionary-itemiterator object at 0x00000000025B6F98>,然后再使用list方法。
  注意返回的结果的顺序并没有遵循特定的顺序。

使用iteritems方法的效率更高(尤其是想要迭代结果的情况下),关于迭代器的概念我们后面会涉及到。

1.4.7. keys和iterkeys方法

  两个方法都是将字典中所有的键以列表的方式返回,keys直接返回结果,iterkeys返回的是一个迭代器。使用上与上一节items和iteritems方法类似。

>>> d = {'name':'yangliehui','age':28}>>> d.keys()['age', 'name']>>> ik = d.iterkeys()>>> list(ik)['age', 'name']

  两种方法的使用见上面的代码示例。

1.4.8. pop方法

  这个方法用来获得对应于给定键的值,然后再将这个键值对从字典中移除。

>>> d = {'name':'yangliehui','age':28}>>> d.pop('name')'yangliehui'>>> d{'age': 28}

1.4.9. popitem方法

  popitem方法类似list.pop方法,但是list.pop方法会弹出列表中最后一个元素,而popitem弹出的是一个随机项,因为字典中没有“最后的元素”或其他有关顺序的概念。若想一个接一个地移除并处理项,这个方法就非常的有效,因为不用首先获取键的列表。

>>> d = {'name':'yangliehui','age':28}>>> d.popitem()('age', 28)>>> d{'name': 'yangliehui'}

尽管popitem和列表的pop方法类似,但是字典中没有与append方法等价的方法。因为字典是无序的,类似于append的方法是没有任何意义的。

1.4.10. setdefault方法

  setdefault方法在某种程度上类似于get方法。我们可以参考上面小节中对get方法的说明。
  除此之外,setdefault方法还能在字典中不含有给定的键的情况下设定相应的值。

>>> d = {}>>> d.setdefault('name','N/A')'N/A'>>> d{'name': 'N/A'}>>> d['name'] = 'yangliehui'>>> d.setdefault('name','N/A')'yangliehui'>>> d{'name': 'yangliehui'}

  上面的例子我们可以看出,当键不存在的时候,setdefault返回默认值并且相应的更新字典。如果键存在就返回相应的值,但不改变字典,默认值是可选的,这点和get方法一样,如果不设定,会默认使用None。

1.4.11. update方法

  update方法可以利用一个字典项更新到另外一个字典:

>>> d = {'name':'yangliehui','age':28}>>> x = {'name':'zhaonan'}>>> d.update(x)>>> d{'age': 28, 'name': 'zhaonan'}>>> ##################################...>>> x1 = {'id':'1001'}>>> d.update(x1)>>> d{'age': 28, 'name': 'zhaonan', 'id': '1001'}

  我们看到后提供的字典的项会更新到原理的字典中,如果有相同的键就会覆盖,如果没有相同的键就添加。
  在看一下下面的代码:

>>> d = {'name':'yangliehui','age':28}>>> d.update(name='zhaonan')>>> d{'age': 28, 'name': 'zhaonan'}

我们发现update方法还可以像上面那样调用,这类似于上面我们学到的dict方法,其实dict方法的使用方式update方法都能使用。

1.4.12. values和itervalues方法

  两个方法都是将字典中所有的键对应的值以列表的方式返回,values直接返回结果,itervalues返回的是一个迭代器。使用上与上一节keys和iterkeys方法类似。

>>> d = {'a':1 ,'b':2 ,'c': 1}>>> d.values()[1, 1, 2]

但是要注意,它与keys和iterkeys方法不同的是,因为值可以允许重复,因此会返回重复的数据。

原创粉丝点击