zoukankan      html  css  js  c++  java
  • python字典和集合

    构造方法与字典推导式

    >>> a = dict(one=1, two=2, three=3)    #法一
    >>> b = {'one': 1, 'two': 2, 'three': 3}    #法二
    >>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))    #法三
    >>> d = dict([('two', 2), ('one', 1), ('three', 3)])    #法四
    >>> e = dict({'three': 3, 'one': 1, 'two': 2})    #法五
    >>> a == b == c == d == e
    True    
    DIAL_CODES = [    #承载成对数据的列表,用于字典推导   
        (86, 'China'),
        (91, 'india'),
        (1, 'United States'),
        (7, 'Russia'),
        (81, 'Japan'), ]
    country_code = {country: code for code, country in DIAL_CODES}  #字典推导式,类似于列表推导式
    print(country_code)
    new_country_code = {code: country.upper() for country, code in country_code.items() if code > 80}  #筛选code值大于60的并将country改为大写
    print(new_country_code)
    #结果
    {'United States': 1, 'Japan': 81, 'Russia': 7, 'india': 91, 'China': 86}
    {81: 'JAPAN', 91: 'INDIA', 86: 'CHINA'}

    dict常见方法(collections库中的defaultdict,Orderedict同样有这些方法)

    1 dict.clear()  //删除字典内所有元素                                             
    2 dict.copy()  //返回一个字典的浅复制
    3 dict.fromkeys(seq[, val])  //创建一个新字典,以序列 seq 中元素做字典的键,val 为字典所有键对应的初始值
    4 dict.get(key, default=None)  //返回指定键的值,如果值不在字典中返回default值
    5 dict.has_key(key)   //如果键在字典dict里返回true,否则返回false    (可用key in dict代替)
    6 dict.items()  //以列表返回可遍历的(键, 值) 元组数组
    7 dict.keys()  //以列表返回一个字典所有的键
    8 dict.setdefault(key, default=None)  //和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
    9 dict.update(dict2)  //把字典dict2的键/值对更新到dict里
    10 dict.values()  //以列表返回字典中的所有值以列表返回字典中的所有值
    11 pop(key[,default])  //删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
    12 popitem()  //随机返回并删除字典中的一对键和值。

    找不到键时的选择

    1.当字典d[k]不能找到正确的键的时候,会抛出keyError异常。上述方法中的dict.get(key, default=None)dict.setdefault(key, default=None)均可解决问题。

    而需要正确区分两个函数的合适场合,当需要更新某个键对应的值时,使用setdefault这个函数则更为合适,因为get函数只是返回default值,并不对字典进行更新。

    2.使用collections中.defaultdict创建字典而不是dict

    实例化defaultdict时,需要给构造方法提供一个可调用对象,这个可调用对象会在__getitem__碰到找不到的键的时候被调用,让__getitem__返回某个默认值。

    以list为例,新建字典d = defaultdict(list),如果new_key在字典中不存在,则d[new_key]会按照以下步骤:

    1)调用list来新建一个列表

    2)把这个列表作为值,‘new_key’作为键,放到d中

    3)返回列表引用。

    其他映射类型

    collections.OrderedDict  //特点:添加键时保持顺序。popitem()方法删除的是最后一个元素,类似;而可用popitem(last=False)来删除第一个元素,类似队列

    collections.ChainMap    //特点:可以容纳多个不同的映射对象,查找时,这些对象会被当做一个整体逐一查找,直到键被找到。

    collections.Counter      //特点:为键(key)维护一个计数器,每次更新一个键时会增加这个计数器。实现了+和-运算来合并记录。most_commot([n])方法,按照次序返回映射里面最常见的n个键和他们的计数。下例:

    from collections import Counter
    ct = Counter('trueorfalse')
    print(ct)
    ct.update('tree')    #更新
    print(ct)
    print(ct.most_common(3))    #获取最多的三个键
    new_ct = Counter('tree')
    print(ct + new_ct)    #加号
    print(ct - new_ct)     #减号
    Counter({'r': 2, 'e': 2, 'u': 1, 'o': 1, 'a': 1, 't': 1, 's': 1, 'l': 1, 'f': 1})
    Counter({'e': 4, 'r': 3, 't': 2, 'u': 1, 'o': 1, 'a': 1, 's': 1, 'l': 1, 'f': 1})
    [('e', 4), ('r', 3), ('t', 2)]
    Counter({'e': 6, 'r': 4, 't': 3, 'u': 1, 'o': 1, 'a': 1, 'f': 1, 'l': 1, 's': 1})
    Counter({'r': 2, 'e': 2, 'u': 1, 'o': 1, 'a': 1, 't': 1, 'f': 1, 'l': 1, 's': 1})

    自定义类型   UserDict

    UserDict不是dict的子类,但UserDict有一个data属性,是dict的实例,data是UserDict最终存储数据的地方。

    UserDict继承的是MutableMapping,MutableMapping继承的是Mapping。

    MutableMapping.update不但可直接使用,而且用在__init__中,让构造方法可以利用各种参数(其他映射类型,可迭代的(key,value)元组对)来新建事例。

    Mapping.get方法在键不存在时,将键转化为字符串查询。

    不可变映射类型 types.MappingProxyType  //返回一个动态视图

    from types import MappingProxyType
    d = {1: 'A'}
    d_proxy = MappingProxyType(d)
    print(d_proxy)
    {1: 'A'}
    d_proxy[2] = 'x'    #不可变,抛出异常
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
    TypeError: 'mappingproxy' object does not support item assignment
    d[2] = 'x'
    print(d_proxy)     #动态变化
    mappingproxy({1: 'A', 2: 'x'})

    集合 (set和frozenset)

    set本身元素必须是可散列的,但frozenset可以。

    构造方法

    s = {1,2,3}    //速度快
    s = set{[1,2,3]}    //常用
    s = frozenset([1, 2, 3, 4, 5, 4])
    s = {i for i in range(5)}    //集合推导式

    一个陷阱:{ }构造的是一个字典而非集合,需用set()方法。

    集合数学运算符(集合s和集合z,,以下方法会修改s)

    交集  s & z  s &= z

    并集  s | z    s |= z

    差集  s z     s = z

    对称差集  s ^ z   s ^= z

    集合比较运算符(集合s和集合z,返回布尔值)

    属于  e in s 

    子集  s <= z

    真子集  s < z

    父集  s >= z

    真父集  s > z

    其他常用方法

    add(e)   //向集合中添加元素e

    clear()   //清空集合

    copy()   //返回集合的浅拷贝

    pop()   //删除并返回任意的集合元素(如果集合为空,会引发 KeyError)

    remove(e)   //删除集合中的e元素(如果元素不存在,会引发 KeyError)

    内置方法

    all()   //如果集合中的所有元素都是 True(或者集合为空),则返回 True。
    any()   //如果集合中的所有元素都是 True,则返回 True;如果集合为空,则返回 False。
    enumerate()   //返回一个枚举对象,其中包含了集合中所有元素的索引和值(配对)。
    len()   //返回集合的长度(元素个数)
    max()   //返回集合中的最大项
    min()   //返回集合中的最小项
    sorted()   //从集合中的元素返回新的排序列表(不排序集合本身)
    sum()   //返回集合的所有元素之和

    字典实现方式(散列表)

    4个问题

    【1】字典和集合的效率?

    【2】字典为什么是无序的?

    【3】所有对象均可作为python中的键?

    【4】为什么不能在迭代时往dict或set中添加元素。

    散列表是一个稀疏数组(含有大量空白元素的数组),散列表单元称为表元。dict的散列表中,每个键值对占用一个表元,分为键的引用和值的引用两部分。表元大小一致,故通过偏移量来读取某个单元。python会设法保证大概有1/3的空白表元【1】,当达到这个阈值时,散列表会被复制到一个新的更大的空间中【2】【4】(复制时会使用散列表算法)

    散列性和相等性:字典必须保证键是可散列的【3】(在生命周期中,散列值是不变的对象);另外如果两个散列对象相等,那么他们的散列值相等,例如1和1.0。

    散列表算法:获取d[k]的值时,会调用hash(k)来计算k的散列值,把这个值最低几位数字当做偏移量【5】,在散列表中查找表元,若表元为空,会抛出keyError异常;若不是空的,则产生散列冲突,算法会在散列值中另取几位,用特殊方法处理后,得到新的偏移量来查找表元。->反复如上步骤,直到产生keyError异常或查找到匹配的键。

    上述特性分别决定了:

    【1】字典在内存中开销巨大

    【2】字典是可能是乱序的;【4】无论何时添加新的键都有可能让字典产生扩容,而这个过程会发生新的散列冲突,导致新散列表的键次序变化;而在迭代时修改字典可能会跳过一些键或迭代字典中已有的键。

    【3】键必须是可散列的

    【5】键查询很快

  • 相关阅读:
    Liquid模板语言参考文档
    Shopify主题title/description等SEO设置
    23个Shopify免费模板值得拥有
    navicate 激活
    idea 内存溢出
    mysql for update 使用说明
    quartz-SimpleSemaphore
    达梦数据库冷备份还原的简单记录
    Beyond Compare 的比较以及导出的简单设置方法
    PG13 离线安装的简单办法
  • 原文地址:https://www.cnblogs.com/lht-record/p/10230310.html
Copyright © 2011-2022 走看看