zoukankan      html  css  js  c++  java
  • Python基础:04映射类型

            字典是Python语言中唯一的映射类型。一个字典对象是可变的,它是一个容器类型,能存储任意个数的Python对象。字典中的数据是无序排列的。

            映射类型也可被称做哈希表,哈希表的算法是获取键,对键执行一个叫做哈希函数的操作,并根据计算的结果,选择在数据结构的某个地址中来存储值。任何一个值存储的地址皆取决于它的键。正因为这种随意性,哈希表中的值是没有顺序的。哈希表一般有很好的性能,因为用键查询相当快。

     

    一:创建字典

            1:dict()

            从Python2.2版本起,可以用工厂方法 dict() 来创建字典。

            如果不提供参数,会生成空字典。若参数是可以迭代的,如序列、迭代器,或是一个支持迭代的对象,那每个可迭代的元素必须成对出现。在每个值对中,第一个元素是字典的键、第二个元素是字典中的值。例子:

    >>> fdict = dict((['x',  1],  ['y', 2]))
    >>> fdict
    {'y': 2,  'x': 1}
    
    >>> dict(zip(('x', 'y'), (1, 2)))
    {'y': 2, 'x': 1}
    
    >>> dict([('xy'[i-1],  i) for i in range(1,3)])
    {'y': 2, 'x': 1} 

            

    如果输入参数是(另)一个映射对象,比如,一个字典对象,对其调用dict()会从存在的字典里复制内容来生成新的字典。新生成的字典是原来字典对象的浅复制版本, 它与用字典的内建方法copy() 生成的字典对象是一样的。但是copy()更快,所以推荐使用copy()

     

            从Python2.3 开始,dict()方法可以接受关键字参数字典:

    >>> dict(x=1, y=2)
    {'y': 2, 'x': 1} 

            

    2:fromkeys()

            从Python2.3 版本起, 可以用内建方法fromkeys()来创建一个"默认"字典,字典中元素具有相同的值 (如果没有给出, 默认为None):

    >>> ddict = {}.fromkeys(('x', 'y'),  -1)
    >>> ddict
    {'y': -1,  'x': -1}
    
    >>> edict = {}.fromkeys(('foo', 'bar'))
    >>> edict
    {'foo': None,  'bar':None} 

     

    二:访问字典

            从Python2.2 开始,可以不必再用keys()方法获取供循环使用的键值列表了。 可以用迭代器来轻松地访问类序列对象(sequence-like objects),比如字典和文件。只需要用字典的名字就可以在 for 循环里遍历字典。

    >>> dict2 = {'name': 'earth', 'port': 80}
    >>>> for key in dict2:
    ... print 'key=%s, value=%s' % (key, dict2[key])
    ...
    
    key=name, value=earth
    key=port, value=80 

     

    要得到字典中某个元素的值, 可以用字典的键查找操作符([ ]):

    >>> dict2['name']
    'earth'

    使用[ ]时,如果在这个字典中没有对应的键,将会产生一个错误:

    >>> dict2['server']
    Traceback (innermost last):
    File "<stdin>", line 1, in ?
    KeyError: server 

            检查一个字典中是否有某个键,是用字典的 has_key()方法, 或者另一种比较好的方法就是从2.2 版本起用的,in 或 not in 操作符。

     

    三:更新和删除字典

            1:更新

            字典的键查找操作符([ ]),既可以用于从字典中取值,也可以用于给字典赋值。如果字典中该键已经存在,则字典中该键对应的值将被新值替代。如果改键不存在,则相当于增加新条目:

    >>> dict2['name'] = 'venus'           # 更新已有条目
    >>> dict2['arch'] = 'sunos5'            # 增加新条目

            2:删除

            以下是删除字典和字典元素的例子:

    del dict2['name']             # 删除键为“name”的条目

    dict2.clear()                     # 删除dict2 中所有的条目

    del dict2                           #删除整个dict2 字典

    dict2.pop('name')            #删除并返回键为“name”的条目

     

    四:字典的比较

            字典的比较不是很有用也不常见。比较算法按照以下的顺序:

            (1)比较字典长度

            如果字典的长度不同,那么用cmp(dict1, dict2) 比较大小时,如果字典 dict1 比 dict2 长,cmp()返回正值,如果 dict2 比 dict1 长,则返回负值。也就是说,字典中的键的个数越多,这个字典就越大。

            (2)比较字典的键

            如果两个字典的长度相同,那就按字典的键比较;键比较的顺序和 keys()方法返回键的顺序相同。这时,如果两个字典的键不匹配时,对这两个(不匹配的键)直接进行比较。当dict1 中第一个不同的键大于dict2 中第一个不同的键,cmp()会返回正值。

            (3)比较字典的值

            如果两个字典的长度相同而且它们的键也完全匹配,则用字典中每个相同的键所对应的值进行比较。一旦出现不匹配的值,就对这两个值进行直接比较。若dict1 比dict2 中相同的键所对应的值大,cmp()会返回正值。

            (4) 完全匹配

            到此为止,每个字典有相同的长度、相同的键、每个键也对应相同的值,则字典完全匹配,cmp函数返回0 值。

     

    五:字典的键

            大多数Python对象都可以作为键;但它们必须是可哈希的对象。所有不可变的类型都是可哈希的,因此它们都可以做为字典的键。像列表和字典这样的可变类型,由于它们不是可哈希的,所以不能作为键。

            在执行中字典中的键不允许被改变。比如创建了一个字典,字典中包含一个元素(一个键和一个值)。可能是由于某个变量的改变导致键发生了改变。这时候你如果用原来的键来取出字典里的数据,会得到KeyError。现在你没办法从字典中获取该值了,因为键本身的值发生了变化。由于上面的原因,字典中的键必须是可哈希的, 所以数字和字符串可以作为字典中的键, 但是列表和其他字典不行。

     

            一个要说明的是问题是数字:值相等的数字表示相同的键。换句话来说,整型数字 1 和 浮点数 1.0 的哈希值是相同的,即它们是相同的键。

            也有一些可变对象(很少)是可哈希的,它们可以做字典的键,但很少见。举一个例子,一个实现了__hash__() 特殊方法的类。因为__hash__()方法返回一个整数,所以仍然是用不可变的值(做字典的键)。

     

            数字和字符串可以被用做字典的键,元组虽然是不可变的,但是元组也有可能包含可变对象。所以用元组做有效的键,必须要加限制:元组中只包括像数字和字符串这样的不可变参数,才可以作为字典中有效的键。

     

    六:映射类型相关函数

            内建函数hash()可以判断某个对象是否可以做一个字典的键。将一个对象作为参数传递给 hash(), 会返回这个对象的哈希值。 只有这个对象是可哈希的,才可作为字典的键 (函数的返回值是整数,不产生错误或异常)。

            如果非可哈希类型作为参数传递给hash()方法,会产生TypeError 错误(因此,如果使用这样的对象作为键给字典赋值时会出错):

    >>> hash([])
    Traceback (innermost last): File"<stdin>", line 1, in ?
    TypeError: list objects are unhashable
    >>> 
    >>> dict2[{}] = 'foo'
    Traceback (most recent call last): File"<stdin>", line 1, in ?
    TypeError: dict objects are unhashable

    七:映射类型内建方法

            1:keys()方法,返回一个列表,包含字典中所有的键(的副本)。

            2:values()方法,返回一个列表,包含字典中所有的值(的副本)。

            3:items(),返回一个包含所有(键, 值)元组(的副本)的列表。这些方法在不按任何顺序遍历字典的键或值时很有用。

    >>> dict2.keys()
    ['port', 'name']
    
    >>> dict2.values()
    [80, 'earth']
    
    >>> dict2.items()
    [('port', 80), ('name', 'earth')]

            4:dict.get(key, default=None)

            对字典dict中的键key,返回它对应的值value,如果字典中不存在此键,则返回default的值,参数default的默认值为None,所以该函数不会引发KeyError异常。该函数也不会改变字典。

     

            5:dict.pop(key [, default])

            如果字典中key键存在,删除并返回dict[key],如果key 键不存在,但是给出了default参数,则返回default。如果没有给出default且key不存在,则引发KeyError 异常。该函数有可能改变字典。

     

            6:update()方法可以用来将一个字典的内容添加到另外一个字典中。字典中原有的键如果与新添加的键重复,那么重复键所对应的原有条目的值将被新键所对应的值所覆盖。原来不存在的条目则被添加到字典中。

            7:clear()方法可以用来删除字典中的所有的条目。

    >>> dict2= {'host':'earth',  'port':80}
    >>> dict3= {'host':'venus',  'server':'http'}
    >>> dict2.update(dict3)
    >>> dict2
    {'server': 'http', 'port': 80, 'host': 'venus'}
    >>> dict3.clear()
    >>> dict3
    {}

            8:copy()方法返回一个字典的副本。注意这只是浅复制。

     

            9:setdefault(key [,default])是自2.0才有的内建方法, 使得代码更加简洁。它实现了常用的语法:如果字典中key存在,则不改变字典,直接返回它的值。如果所找的key在字典中不存在,则给这个键赋default并返回default,default默认为None。

    >>> myDict = {'host': 'earth', 'port': 80}
    >>> myDict.setdefault('port', 8080)
    80
    
    >>> myDict.setdefault('prot', 'tcp')
    'tcp'
    
    >>> myDict.items()
    [('prot', 'tcp'), ('host', 'earth'), ('port', 80)]

            10:因keys(),items(), 和 values()方法的返回值都是列表。数据集如果很大会导致很难处理,因此iteritems(), iterkeys(), 和itervalues() 方法被添加到 Python2.2 中。这些函数与返回列表的对应方法相似,只是它们返回惰性赋值的迭代器,所以节省内存。

     

    八:其他

            要避免使用内建对象名字作为变量的标识符。不要用 dict, list, file, bool, str, input, len 这样的内建类型为变量命名。

     >>> print 'host %(name)s is runningon port %(port)d' %dict2
    host venus is running on port 6969

            上面的print语句展示了另一种使用字符串格式符( %)的方法。用字典参数可以简化print 语句,因为这样做你只须用到一次该字典的名字,而不用在每个元素出现的时候都用元组参数表示。

  • 相关阅读:
    day01
    用表单验证数据(1)
    用表单验证数据
    表单
    ORM作业
    mysql完全卸载大全
    mycat特点及用途
    ajax 跨域请求解决方案
    myeclipse使用SVN团队开发
    配置mybatis错误总结
  • 原文地址:https://www.cnblogs.com/gqtcgq/p/7247213.html
Copyright © 2011-2022 走看看