金沙国际官网_金沙国际平台登录

因为这个金沙国际官网_金沙国际平台登录网站与很多的大型澳门赌场都有合作,金沙国际官网_金沙国际平台登录尽职尽责,高效执行,保持好奇心,不断学习,追求卓越,点击进入金沙国际官网_金沙国际平台登录马上体验吧,所以现在也正式地开始了营业。

您的位置:金沙国际官网 > 编程 > 学习笔记17,字典和集合

学习笔记17,字典和集合

发布时间:2019-11-04 21:11编辑:编程浏览(106)

    映射的再讨论 

    '''
        python标准库里面的映射类型都是可变的,有时候需要使用不可变的映射,从python3.3开始,types模块中引入了
        MappingProxyType类,如果给这个类一个映射,那么它会返回这个映射的试图,该试图是动态的,原映射如果有改动
        可立即通过这个试图观察到,但是这个试图无法对该映射进行修改。
    '''
    from types import MappingProxyType
    
    if __name__ == "__main__":
        d = {'one':1, 'two':2, 'three':3}
        d_proxy = MappingProxyType(d)
        print(d_proxy)     # {'three': 3, 'two': 2, 'one': 1}
        print(d_proxy['one'])  # 1
        for k, v in d_proxy.items():
            print(k, v)
    
        #d_proxy['four'] = 4   # 报错:TypeError: 'mappingproxy' object does not support item assignment
        d['four'] = 4
        print(d_proxy)     # {'two': 2, 'three': 3, 'four': 4, 'one': 1}

     

      另外,《流畅的python》77页到80页对散列表算法以及字典、集合的效率、平时需要注意的问题进行了比较详细的探讨,建议严谨并有兴趣的同仁阅读,该部分内容对理解字典类型无比有益,场景中捉摸不透的莫名其妙的bug可能会迎刃而解。

       重要的结论摘录如下:

      (1)键必须是可散列的

      (2)字典在内存上的开销巨大

      (3)键查询很快

      (4)键的次序取决于添加顺序

      (5)往字典里添加新键可能会改变已有键的顺序

     

    个人对selenium的理解:

    1.使用selenium操作浏览器,实际上是使用selenium框架下的webdriver启动各浏览器的驱动实现对浏览器的操作的。以下两句代码即可启动firefox浏览器驱动

    from selenium import webdriver

    brower=webdriver.Firefox()

    因此,selenium的作用实际上相当于模拟了用户操作浏览器(点击链接、按钮、填写表单、截屏、控制窗口大小、安装插件、配置证书等操作)。
    webdriver能够操纵浏览器的原因是webdriver封装了浏览器的API。由于不同厂家生产的浏览器API实现方式不大相同,因此webdriver也分FirefoxDriver、ChromeDriver、iOSDriver等驱动。
    调用不同的浏览器,我们除了要安装导入webdriver模块外,还要下载相对应浏览器的驱动。
    
    2.webdriver能够定位节点,
    

    selenium学习教程:

    1、Mr.南柯

    缓存 I/O 的缺点
      数据在传输过程中需要在应用程序地址空间和内核进行多次数据拷贝操作,这些数据拷贝操作所带来的 CPU 以及内存开销是非常大的。

    本文主要内容

    可散列类型

    泛映射类型

    字典

        (1)字典推导式

      (2)处理不存在的键

        (3)字典的变种

    集合

    映射的再讨论

     

    python高级——目录

    文中代码均放在github上:https://github.com/ampeeg/cnblogs/tree/master/python高级

     

    二、selenium相关方法

    1、Python Selenium 常用方法总结

    三、selenium各种包

    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    

     

    8.缓存 I/O 

    字典

    '''
        字典是python内置类型中唯一的映射,先看创建字典的几种方法
    
        1、对象创建
        2、大括号
        3、zip
    '''
    
    if __name__ == "__main__":
        # 1、利用实例化对象的方法创建
        a = dict(key1=1, key2=2, all=[1, 2, 3])
        b = dict([('key3', 3), ('key4', 4)])
        c = dict({"key5": 5, "key6": 6})
    
        print("a:", a)     # a: {'key1': 1, 'all': [1, 2, 3], 'key2': 2}
        print("b:", b)     # b: {'key3': 3, 'key4': 4}
        print("c:", c)     # c: {'key6': 6, 'key5': 5}
    
        # 2、直接使用大括号
        d = {"key7": 7, "key8": 8}
        print("d:", d)     # d: {'key8': 8, 'key7': 7}
    
        # 3、使用zip
        e = dict(zip(("key9", "key10", "key11"), [9, 10, 11]))
        print("e:", e)     # e: {'key11': 11, 'key10': 10, 'key9': 9}

    (1)字典推导式

     

    '''
        字典推导式:字典推导式的创建方法同列表推导式类似
    
        以下直接引用《流畅的python》中的例子
    '''
    
    
    if __name__ == "__main__":
        DIAL_CODES = [
            (86, 'China'),
            (91, 'India'),
            (1, 'United States'),
            (62, 'Indonesia'),
            (55, 'Brazil'),
            (92, 'Pakistan'),
            (880, 'Bangladesh'),
            (234, 'Nigeria'),
            (7, 'Russia'),
            (81, 'Japan'),
        ]
    
        country_code = {country: code for code, country in DIAL_CODES}
        print(country_code)   # {'Russia': 7, 'Indonesia': 62, 'Brazil': 55, 'China': 86, 'India': 91, 'Bangladesh': 880, 'Pakistan': 92, 'United States': 1, 'Nigeria': 234, 'Japan': 81}
    
        code_upper = {code: country.upper() for country, code in country_code.items() if code < 66}
        print(code_upper)     # {1: 'UNITED STATES', 7: 'RUSSIA', 62: 'INDONESIA', 55: 'BRAZIL'}
    (2)处理不存在的键
    
    '''
        处理找不到的键
    
        在实际场景中,当使用d[key]的方法查找数据的时候,如果找不到该键,python会抛出KeyError异常;
        如果是取值操作,可以使用d.get(key, default)来解决,可以给找不到的键一个默认的值
        但是如果要给更新某个不存在键对应的值的时候,就稍显麻烦了,可以使用以下方法解决:
            1、用setdefault处理dict找不到的键
            2、使用defaultdict对象
            3、__missing__方法
    '''
    
    class Foo:
        def __init__(self, name=None):
            self.name = name
    
        def __repr__(self):
            return str(self.name)
    
        def setattr(self, key, value):
            self.__setattr__(key, value)
            return self
    
    
    if __name__ == "__main__":
        d1 = {}
        print(d1.get("key", "default"))   # default   使用d.get(key, default)的方法取值
    
    
        # 1、用setdefault处理dict找不到的键
        d2 = {}
        d2.setdefault("key", [x for x in "adfaf"])  # setdefault虽然是set名字,但是是取值操作,只有当键不存在时才进行赋值,并返回该值
        l = d2.setdefault("key", [])
        print(l)                                    # ['a', 'd', 'f', 'a', 'f']
    
        d2.setdefault("key2", []).extend([1, 2, 3]) # 返回空列表,所以可在后面直接使用方法extend
        print(d2)                                   # {'key': 'default', 'key2': [1, 2, 3]}
    
        # 2、使用defaultdict对象
        #  在python中,还有一些dict的变种类型,defaultdict为其中一种,位于collections中
        from collections import defaultdict
    
        dic = defaultdict(list)                    # 将list的构造方法作为default_factory(只有__getitem__找不到值时调用)
        dic["key"].extend([1, 2, 3])               # dic中不含有"key"键,此时default_factory会被调用,创造一个空列表,并连接[1, 2, 3]
        print(dic["key"])                # [1, 2, 3]
    
        dic = defaultdict(Foo)           # 将Foo的构造方法作为default_factory创建一个defaultdict
        print(dic["key"].setattr("name", "default"))                # default
    
        # 3、__missing__方法
        # 所有的映射类型在找不到键的时候,都会牵扯到__missing__方法;如果在__getitem__找不到键的时候,python就会自动调用它
        # 另外,__missing__方法只会被getitem调用,对get或者__contains__没有影响
    
        class My_dict(dict):
            def __missing__(self, key):
                print("正在调用__missing__...")
    
        mdict = My_dict(one=1, two=2, three=3)
        print(mdict)     # {'two': 2, 'three': 3, 'one': 1}
        mdict["key"]     # 正在调用__missing__...
    (3)字典的变种
    
    '''
        在python中虽然只有dict为映射类型,但是dict有很多变种,上面defaultdict就是,除此之外还有:
    
        (1)OrderedDict: 有顺序的字典
         (2) ChainMap: 可以容纳数个不同的映射对象
         (3) Counter:  给键准备一个整数计数器,每次更新键的时候会增加该计数器
        (4)UserDict:  将标准的dict用python实现了一遍
    '''
    
    
    from collections import OrderedDict, ChainMap, Counter, UserDict
    
    if __name__ == "__main__":
        # 1、OrderedDict
        d = OrderedDict()
        d['one'] = 1
        d['two'] = 2
        d['three'] = 3
        for _ in range(10):
            print("%d次:" % _)
            for k, v in d.items():
                print("**", k, v)        # OrderedDict迭代的时候的顺序总是跟插入顺序一致
    
    
        # 2、ChainMap
    
        pylookup = ChainMap(d, globals())   # d和globals()都是映射类型,ChainMap会将其组合
        for v, k in pylookup.items():
            print(v, k)
    
        # 3、Counter
        ct = Counter('asfjlajslfjals')
        print(ct)      # Counter({'j': 3, 'l': 3, 's': 3, 'a': 3, 'f': 2})
                       # 存储的是每个字母出现的次数
        ct.update('jjjjjjjjlllllllll')
        print(ct)      # # Counter({'l': 12, 'j': 11, 's': 3, 'a': 3, 'f': 2})
    
        import random
        ct2 = Counter([random.randrange(1, 5) for _ in range(100)])   # 列表推导式创建Counter
        print(ct2)     # Counter({1: 30, 2: 24, 4: 24, 3: 22})
    
        ct3 = Counter((random.randrange(1, 5) for _ in range(100)))   # 生成器创建Counter
        print(ct3)      # Counter({2: 40, 3: 23, 4: 20, 1: 17})
    
        class Foo:
            def __init__(self, num):
                self.l = [random.randrange(1, 5) for _ in range(num)]
    
            def __iter__(self):
                return iter(self.l)
    
        ct4 = Counter(Foo(100))            # 可迭代对象创建Counter
        print(ct4)      # Counter({2: 31, 3: 25, 4: 25, 1: 19})
    
        # 4、UserDict
        # 创建自定义的映射类型,一般以UserDict为基类
    
        class My_dict(UserDict):
            def __missing__(self, key):
                if isinstance(key, str):
                    raise KeyError(key)
                return self[str(key)]
    
            def __contains__(self, key):
                return str(key) in self.data
    
            def __setitem__(self, key, item):
                print("调用__setitem__。。。")
                self.data[str(key)] = item
    
        mdict = My_dict()
        mdict["one"] = 1      # 调用__setitem__。。。(下同)
        mdict["two"] = 2
        mdict["three"] = 3
        print(mdict)   # {'three': 3, 'one': 1, 'two': 2}

     

    一、定位相关内容:

    1、定位不到的五种情况及解决办法

    2、iframe影响定位后的切换与处理

    主要的三个函数:

    brower.switch_to.frame(reference)  切入referrence这个frame中

    brower.switch_to.parent_frame()  切回父frame中

    brower.swith_to.default_content() 切回主页面中,如果要在几个平行的frame中切换,必须添加这一句回到主页面后再切换至其他iframe中

    例子

    python高级系列文章目录

    python高级——目录

     

     

     

    3.gevent模块
    gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。

    集合

    '''
        集合对于很多人并不陌生,中学阶段就已经接触过。集合具有:
        (1)确定性:每一个对象都能确定是不是某一集合的元素,没有确定性就不能成为集合
        (2)互异性:集合中任意两个元素都是不同的对象
        (3)无序性:{a,b,c}{c,b,a}是同一个集合
    
        在python中,set中的元素必须是可散列的,但set本身不可散列(但是frosenset是可散列的)
    
    
        另外:set实现了很多基础运算
        &(交集)、|(并集)、-(差集)
    '''
    
    
    if __name__ == "__main__":
        # 创建集合
        s1 = set([1, 2, 3])
        s2 = {1, 2, 3, 4}
        print(s1, s2)     # {1, 2, 3} {1, 2, 3, 4}
    
        # 集合推导式
        s3 = {x**2 for x in range(10)}
        print(s3)         # {0, 1, 64, 4, 36, 9, 16, 49, 81, 25}

     

    set的操作方法很多,本文截自<流畅的python>一书,如下三个表:
    
    表一:集合的数学方法
    

     

    表2:集合的比较运算

     

    表3:集合的其他运算

     

     

    泛映射类型

    '''
        泛映射类型就是广义上的对应关系,在数学中,我们将集合A对应集合B中的对应法则称为"映射"(Mapping)
        同样,在python里,我们称"键值对"为映射,这其实也是一种对应法则
        如果一个数据类型是映射,那么它肯定属于collections.abc.Mapping,可使用isinstance函数测试
    
        PS: 字典是 Python 语言中唯一的映射类型。映射类型对象里哈希值(键) 和指向的对象(值)是一对多的关系。
    '''
    
    from collections import abc
    
    # 我们测试一些常用的类型是不是映射
    if __name__ == "__main__":
        print(isinstance({}, abc.Mapping))      # True   字典是典型的键值对
        print(isinstance([1, 2], abc.Mapping))  # False  列表是序列
        print(isinstance((1, 2), abc.Mapping))  # False  元组是序列
        print(isinstance('adfasfd', abc.Mapping))  # False  字符串也是序列
    '''
       大家可以查看_collections_abc.py源代码,里面基本的类型包含:
        ["Awaitable", "Coroutine", "AsyncIterable", "AsyncIterator",
        "Hashable", "Iterable", "Iterator", "Generator",
        "Sized", "Container", "Callable",
         "Set", "MutableSet",
         "Mapping", "MutableMapping",
         "MappingView", "KeysView", "ItemsView", "ValuesView",
         "Sequence", "MutableSequence",
        "ByteString",
        ]
    '''

     

    '''
        如果我们自己想定义一个映射类型的对象,那么必须实现__getitem__、__iter__、__len__方法
    
        PS:关于该部分的原理,本人暂未查看说明文档,毕竟现实中几乎不可能自定义映射;有兴趣的同志可深入钻研。
    '''
    
    
    class Foo(abc.Mapping):
        def __init__(self, name):
            self.name = name
    
        def __getitem__(self, item):
            return self.name
    
        def __iter__(self):
            return iter(str(self.name))
    
        def __len__(self):
            return len(self.name)
    
    
    print(isinstance(Foo("123"), abc.Mapping))      # True

     

    4.gevent默认检测不了urllib的i/o操作

    可散列类型

    '''
        可散列数据类型(也称可hash)————我理解"可散列"就是"可hash"
        可hash的对象需要实现__hash__方法,返回hash值;另外为了与其他对象比较还需要有__eq__方法
    
        原子不可变数据类型(str、bytes和数值类型)都是可散列的,可散列对象必须满足下列要求:
        (1)实现了__hash__方法,并且所得到的hash值是不变的
        (2)实现了__eq__方法,用来比较
        (3)若a == b 为真,那么hash(a) == hash(b)也是真
    '''
    
    
    # 创建类Foo,并实现__hash__和__eq__
    
    class Foo:
        def __init__(self, name):
            self.name = name
    
        def __hash__(self):
            print("正在hash...")
            return hash(self.name)
    
        def __eq__(self, other):
            print("正在比较...")
            return self.name == other.name
    
        def __repr__(self):
            return self.name
    
    
    if __name__ == "__main__":
    
        f1 = Foo("小李")
        f2 = Foo("小红")
        f3 = Foo("小李")
    
        s = set([f1, f2, f3])        # 集合实现不重复的原理正好利用了散列表
        print(s)                     # {小红, 小李}
        print( f1 == f3, hash(f1) == hash(f3))      # True True 满足可散列对象的第三个条件
    '''
        对于元组来说,只有当一个元组包含的所有元素都是可hash的情况下,它才是可hash的
    '''
    t1 = (1, 2, 3, [1, 2])   # 元组里的列表的值是可变的,所以不可hash
    try:
        print(hash(t1))
    except Exception as e:
        print(e)             # unhashable type: 'list'
    
    t2 = (1, 2, 3, (1, 2))   # 元组里的元素都是不可变的,并且第二层元组里面的元素也不可变,所以可hash
    print(hash(t2))          # 3896079550788208169
    
    t3 = (1, 2, 3, frozenset([1, 2]))
    print(hash(t3))          # -5691000848003037416

     

    1.协程(微线程)
    协程是一种用户态的轻量级线程。
    协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:

     

    6.事件驱动模型
    目前大部分的UI编程都是事件驱动模型,如很多UI平台都会提供onClick()事件,这个事件就代表鼠标按下事件。事件驱动模型大体思路如下:
      1). 有一个事件(消息)队列;
      2. 鼠标按下时,往这个队列中增加一个点击事件(消息);
      3). 有个循环,不断从队列取出事件,根据不同的事件,调用不同的函数,如onClick()、onKeyDown()等;
      4). 事件(消息)一般都各自保存各自的处理函数指针,这样,每个消息都有独立的处理函数;

    本文由金沙国际官网发布于编程,转载请注明出处:学习笔记17,字典和集合

    关键词: