Python学习笔记3

作者: MetaT1an | 来源:发表于2018-08-25 13:29 被阅读7次

    数据类型(补充) 上一部分

    • 集合
    • 时间日历

    函数

    • 函数的参数
    • 返回值
    • 偏函数
    • 高阶函数
    • 匿名函数
    • 闭包
    • 装饰器
    • 生成器

    集合

    无序的不可随机访问的不可重复的元素集合

    • 与数学中的集合类似,可以进行集合的交、并、差、补等操作。
    • 分为可变集合不可变集合
      • set: 可以进行增、删、改操作
      • frozenset: 创建好之后,无法再做修改。
    可变集合的表示
    # 直接表示
    
    s = {1, 2, 3, 4}
    print(s, type(s))  # {1, 3, 4, 2} <class 'set'>
    
    # set(Iterable)
    
    s1 = set("abc")
    s2 = set([1, 2, 3])
    
    print(s1, s2)   # {'a', 'b', 'c'}   {1, 2, 3}
    
    # 集合推导
    # 参考列表推导
    
    s = {x for x in range(3)}
    print(s)    # {1, 0, 2}
    
    不可变集合
    # frozenset(iterable)
    
    fs = frozenset("abc")
    print(fs)   # frozenset({'a', 'c', 'b'})
    
    # 集合推导
    
    fs = frozenset(x**2 for x in range(1, 6) if x % 2)
    print(fs)   # frozenset({1, 25, 9})
    
    注意事项
    • 创建空集合
      # 错误做法
      s = {}    # 实际上构建了一个空字典
      
      s = set()     # 空集合
      
    • 集合中的元素必须是可哈希的值(不可变类型)。
    • 集合中元素若出现重复,则会被合并成一个。
      # 多用于给列表元素进行去重
      
      li = {1, 2, 2, 3, 3}
      li = list(set(li))
      print(li)     # [1, 2, 3]
      
    集合的操作
    • 单集合操作

      s = {1, 2, 3}
      
      #-----------------------------------------
      # 新增元素
      # 1.集合可变  2.新增元素可哈希
      
      s.add(4)
      print(s)  # {1, 3, 2, 4}
      
      #-----------------------------------------
      # 删除元素
      # 1.remove(element)
      # 删除指定的元素,若无该元素,报错
      
      s.remove(2)
      print(s)      # {1, 3}
      
      # 2.discard(element)
      # 删除指定的元素,若无该元素,pass
      
      s.discard(2)
      print(s)      # {1, 3}
      s.discard(666)
      print(s)      # {1, 3}
      
      # 3.pop(element)
      # 删除并返回指定元素,若无该元素,报错
      # 省略 element,不指定删除元素,进行随机删除;集合为空,报错
      
      s.pop(1)
      print(s)      # {2, 3}
      
      s.pop()       
      print(s)      # {2}
      
      s.pop()   
      print(s)      # set()  //空集合的意思
      
      # 4.clear()
      # 清空集合,集合依然存在
      
      s.clear()
      print(s)  # set()
      
      #-----------------------------------------
      # 遍历集合
      # 1.for in
      
      for v in s:
        print(s, sep=' ')   # 1 2 3
        
      # 2.迭代器
      its = iter(s)
      
      print(next(its))  # 1
      print(next(its))  # 2
      print(next(its))  # 3
      
    • 多集合操作

      • intersection(iterable):

        # 求交集,参数是可迭代类型
        s1, s2 = {1, 2, 3, 4, 5}, {9, 8, 8, 5, 4}
        
        res = s1.intersection(s2)
        print(res)                  # {4, 5}
        # s1也可以是frozenset,返回结果也是frozenset
        
        # 可以使用逻辑运算符来完成
        print(s1 & s2)      # {4, 5}
        
      • intersection_update(iterable)

        # 更新调用该方法的对象
        s1, s2 = {1, 2, 3, 4, 5}, {9, 8, 8, 5, 4}
        s1.intersection_update(s2)
        print(s1)       # {4, 5}
        
      • union(iterable):

        # 求并集,参数是可迭代类型
        s1, s2 = {1, 2, 3}, {2, 3, 4}
        
        res = s1.union(s2)
        print(res)          # {1, 2, 3, 4}
        
        # 可以使用逻辑运算符来完成
        print(s1 | s2)      # {1, 2, 3, 4}
        
      • update(iterable)

        s1, s2 = {1, 2, 3}, {2, 3, 4}
        s1.update(s2)
        print(s1)       # {1, 2, 3, 4}
        
      • difference(iterable)

        # 求差集
        s1, s2 = {1, 2, 3}, {2, 3, 4}
        res = s1.difference(s2)
        print(res)          # {1}
        
        # 逻辑运算符
        print(s1 - s2)      # {1}
        
      • difference_update(iterable):

        s1, s2 = {1, 2, 3}, {2, 3, 4}
        s1.difference_update(s2)
        print(s1)       # {1}
        
      • 判定操作

        # isdisjoint() 两个集合是否不相交
        # isuperset()  一个集合是否包含另一个集合
        # issubset()   一个集合是否包含于另一个集合
        

    时间日历

    time模块
    • 获得当前时间戳
      # 获得从 1970年1月1日到现在的时间秒数
      
      import time
      t = time.time()
      
      yearSpan = t / (60 * 60 * 24 * 365)
      print(yearSpan)       # 48.6441059296045
      
    • 获得时间元组
      # 根据所给的时间戳,返回当时的时间信息
      
      import time
      t = time.time()
      
      res = localtime(t)
      print(res)    # time.struct_time(tm_year=2018, tm_mon=8, tm_mday=12, tm_hour=10, tm_min=22, tm_sec=4, tm_wday=6, tm_yday=224, tm_isdst=0)
      
    • 获得格式化的时间
      # 根据所给定的时间戳,返回一个更加可读的时间
      
      import time
      t = time.time()
      
      res = time.ctime(t)
      print(res)        # Sun Aug 12 10:33:58 2018
      
    • 获得格式化的时间字符串
      # time.strftime(格式字符串, 时间元组)
      
      res = time.strftime("%y-%m-%d %H:%M:%S", time.localtime())
      print(res)    # 18-08-12 10:39:28
      
      res = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
      print(res)    # 2018-08-12 10:39:50
      
    • 获取当前cpu时间
      # 常用来统计一段代码的执行时间
      import time
      
      # IDLE环境测试
      
      start = time.clock()
      for i in range(0, 10)
          print(i, end=' ')
      end = time.clock()
      
      print(end - start)    # 0.02806393769252448
      
    • 休眠
    # 线程休眠
    
    # 每隔一秒打印一个数字
    import time
    
    n = 0
    while True:
        print(n)
        time.sleep(1)   # 参数单位是秒
    
    datetiem模块

    模块内部有多个datetimedatetime。使用时选择合适的类进行操作就行了

    • 获取当天的日期
      import datetime
      t = datetime.datetime.now()
      
      print(type(t))    # <class 'datetime.datetime'>
      print(t)          # 2018-08-12 11:04:12.982890
      print(t.year)     # 2018
      print(t.month)    # 8
      
      
    • 计算n天之后的日期
      import datetime
      
      t = datetime.datetime.today()
      res = t + datetime.timedelta(days=7)
      print(t, res, sep='|')    # 2018-08-12 11:10:31.995501|2018-08-19 11:10:31.995501
      
    • 获得两个日期的时间差
      import datetime
      
      first = datetime.datetime(2018, 9, 10, 12, 0, 0)
      second = datetime.datetime(2018, 10, 1, 0, 0, 0)
      
      res = second - first
      print(res)    # 20 days, 12:00:00
      

    函数

    • 将一段代码集中到一块,起一个名字,下次可以根据这个名字再次使用这个代码块。
    • 作用
      • 方便代码重用
      • 分解任务,简化程序逻辑
      • 使代码更加模块化
    函数的参数

    所有的传参方式都是传引用,注意列表做参数和数值做参数容易出现的问题。

    • 单个参数

    • 多个参数

      # 定义方式
      def funName(arg1, arg2, arg3...):
      
      # 调用方法
      funName(arg1, arg2, arg3...)      # 形参和实参一一对应
      funName(arg2=v1, arg3=v3, arg1=v1)    # 指明形参的名称,不用严格按照顺序
      
    • 不定长参数

      # 1. 利用元组的拆包装包
      def mySum(*args):
          print(type(args))      # <class 'tuple'>
          print(args)       # (1, 2, 3, 4)
          print(*args)      # 拆包操作 1, 2, 3, 4
          
          for v in args:
              # todo ...
      # 装包,将传入的参数装入一个元组中,args就成了一个元组对象
      # 拆包,将一个元组中的元素拆分出来,*args就成了参数序列
              
      # 2. 利用字典的键值对
      def myInfo(**args):
          print(type(args))     # <class 'dict'>
          
          # todo ...
      
      myInfo(name="rity", age=12)
      
    • 默认参数

      # 调用某些函数时,可以省略某些参数,采用定义时指定的值
      # 若不省略,则以调用时输入的为准
      
      def sorted(iterable, reverse=False):
          # todo...
      
      sorted([1, 3, 2, 5], reverse=True)
      
    返回值
    • 返回语句标志着函数的结束,一个函数最好只有一处返回语句
    • 如果想返回多个数据,可以把数据包装成一个集合,整体返回(列表,元组,字典...)
    def funName():
        # todo...
        return data
    
    偏函数
    • 对于一个默认值较多的函数,有时我们需要重复用到其中的部分默认值,每次指定默认值比较麻烦。
    • 可以将其中的默认值先赋值好,然后封装成一个新的函数,这就是偏函数。
    import functools
    
    numStr = "100010"
    res = int(numStr, base=2)
    print(res)      # 34
    
    int2 = functools.partial(int, base=2)   # 重新封装,构成偏函数
    print(int2(numStr))     # 34
    
    高阶函数
    • 一个函数的参数可以是另外一个函数
    def calculate(a, b, cal_fun):
        print(cal_fun(a, b))
    
    def sum(a, b):
        return a + b
        
    def sub(a, b):
        return a - b
        
    calculate(2, 3, sum)    # 5
    calculate(2, 3, sub)    # -1
    
    匿名函数
    • lambda表达式
    • 没有名字的函数
    res = (lambda x, y : x + y)(1, 2)
    print(res)  # 3
    
    fun = lambda x, y : x + y
    print(fun(2, 3))    # 5
    
    # 更多的是配合 map(), reduce()等函数进行使用
    
    闭包
    • 在函数嵌套定义的前提下
    • 内层函数引用了外层函数的变量
    • 外层函数把内层函数当做返回值
    def line_config(content, length):
        
        define line():
            print(content * length)
            
        return line
    
    line1 = line_config("-", 5);
    line2 = line_config("*", 6)
    
    line1();    # -----
    line2();    # ******
    
    • 作用域问题:内层函数要修改外层函数的变量,要使用nonlocal进行声明,否则变量属于内层函数。
    def test():
        num = 10
        
        def test2():
            nonlocal num    # test中的 num被修改
            num = 666
        
        return test2
    
    • 当内层函数使用外层的变化量时,注意值得情况
    def test():
        funs = []
        for i in range(1, 4):
        
        def test2():
            print(i)
    
        funs.append(test2)
        return funs
        
    myFuns = test()
    
    myFuns[0]()     # 3     // 函数在运行时才会去确定变量的值
    myFuns[1]()     # 3     // 运行时,索引 i的值已经发生变化了
    myFuns[2]()     # 3
    
    装饰器
    • 在调用目标函数之前,对这个函数对象进行装饰(增加一些其他功能)。
    • 函数的名字不能改变
    • 函数体内部的代码不能发生改变
    def check(func):
        
        def inner():
            print("登录验证...")
            func()
        
        return inner()
        
    # 在 fss()和 ftp()执行之前,都会送入 check()进行包装
    
    @check          
    def fss():
        print("发说说")
    
    # 上面三行等价于 fss = check(fss)
    
    @check
    def ftp():
        print("发图片")
    
    # 上面三行等价于 ftp = check(ftp)
        
    # 主业务逻辑如下:
    
    flag = 1
    if flag == 1:
        fss()       # 登录验证...
    else:           # 发说说
        ftp()
    
    • 多个装饰器的调用顺序
    def one(func):
        print('----1----')
        def two():
            print('----2----')
            func()
        return two
    
    def a(func):
        print('----a----')
        def b():
            print('----b----')
            func()
        return b
    
    @one
    @a
    def demo():
        print('----3----')
    
    demo()
    
    # 运行结果  //从下到上装饰,从上到下执行,分析略
    # 装饰的过程就相当于你把一件礼物一层一层的进行包装,先包装内层
    # 执行的过程就是把礼物拆开,最外面的包装先被拆开
    ----a----
    ----1----
    ----2----
    ----b----
    ----3----
    
    • 带有参数的函数进行装饰
    def zsq(funcs):
        
        def inner(*args, **kwargs):     # 装包
            print("-" * 5)
            func(*args, **kwargs)       # 拆包
        return inner
    
    @zsq
    def fun1(n1, n2, n3):
        print(n1, n2, n3)
        
    @zsq
    def fun2(n):
        print(n)
        
    fun1(1, 2, n3=8)    # 1 2 8
    fun2(3)     # 3
    
    • 对带有返回值的函数进行装饰
    def zsq(funcs):
        
        def inner(*args, **kwargs):     # 装包
            print("-" * 5)
            res = func(*args, **kwargs)       # 拆包
        return res
        
    @zsq
    def fun1(n1, n2, n3):
        return sum(n1, n2, n3)
    
    fun1(1, 2, 3)
    
    • 带有参数的装饰器
    def getzsq(char):
    
        def zsq (func):
        
            def inner():
                print(char * 5)
                func()
            
            return inner
        
        return zsq
        
    @getzsq("*")
    def f():            # *****
        print("666")    # 666
        
    @getzsq("-")
    def f1():           # -----
        print("666")    # 666
    
    生成器
    • 是一个特殊的迭代器
    • 特性:
      • 惰性计算数据,节省内存
      • 能够记录状态,通过next()函数,访问下一个状态
    • 使用方式
    # 生成器表达式
    l = (i for i in range(1, 10000000) if i % 2)
    print(type(l))        # <class 'generator'> // 不是元组推导,没有元组推导式
    
    print(next(l))      # 1
    print(next(l))      # 3
    
    for i in l:
        print(i)        # 循环打印出所有满足条件的值
        
    # 生成器函数
    def test():
        for i in range(1, 9):
            yield i
    
    g = test()
    print(next(g))      # 1
    print(next(g))      # 2
    

    相关文章

      网友评论

        本文标题:Python学习笔记3

        本文链接:https://www.haomeiwen.com/subject/pffgiftx.html