跳转至

Note

注意点


  • for x in iterable

    • 如果in后面==创建了新实例==可理解为==只被评估最初一次==,x就遍历最初一次创建的新实例,不会随s的变化而改变 --- for x in s[:]:
    • 而如果in后面就是==没创建新实例==,则会被==反复评估==,x遍历的就是s,会随s变化而变化 --- for x in s:
      • 如果采用这种遍历方式要格外小心分析,如果只是extend还好,如果还有remove的话是会影响遍历的,比如我先遍历了第一个,但是第一个在过程中被删了,第二个成了第一个,这样我将不会再遍历新的第一个,即第二个无法被遍历到
    • 但是对于while循环来讲,无论如何它都是会被反复评估的
    • 可见 example里的forin
  • andor 都从左往右执行,遵循短路机制

    • and 执行到 False 时短路并返回False
    • or 执行到 非 False 时短路并返回 非 False 的值

    • and 如果全为 True ,则返回最后一个的值

    • or 如果全为 False,则返回False
  • python的赋值操作

  • list的切片

    • 将切片赋值给变量(单独的切片实例) --- 先创建一个切片长度的新list实例,将原list相应位置的元素依次赋值过去(可变浅拷贝、不可变深拷贝)
    • 将变量(list)赋值给切片 --- 先将原list切片范围去除,并创建与变量同长度的元素框,再用变量依次赋值过去(可变浅拷贝、不可变深拷贝)
  • 函数参数定义法

    • 关键字(+默认参数)
    • *args接任意数量的位置参数
    • **kwargs接受任意数量的关键字参数
    • 在函数定义中使用 *,表示后面的参数只能用关键字方式传入
    • 在函数定义中使用 /,表示前面的参数只能用位置传递
  • 函数参数传递法

    • 位置参数与关键字传参混用时注意 --- ✅ 规则:位置参数要在关键字参数前面
    • *args 函数参数表示法:f(1, 2, 3) 等效于 f(*[1, 2, 3]) or f(*(1,2,3)) 对list或tuple解包
    • 使用 **kwargs字典进行解包传参
    • *args**kwargs 同时使用前者在前,后者在后
  • Python中一般函数的调用过程

    • 在当前环境评估参数的值
    • 函数创建新Frame,将值与symbol依次绑定
    • 执行历程返回最终值
  • 分析定义和调用被装饰器修饰的函数的情形

    • 定义
      • 装饰器函数的历程会在==被修饰函数定义时==执行
      • 一直执行装饰器函数的例程,直到执行完 直接调用被修饰函数的装饰器
    • 调用
      • 执行 ==直接调用被修饰函数装饰器==的返回函数
  • 在python中的作用域不是像C里面那样由框决定,而是由Frame决定,在某个Frame定义的Symbol都会被绑定到该Frame上

    • Symbol的lookup策略是
      • 先在本Frame中查看、然后再在父Frame查看
    • 另外,Python的作用域采用 Lexical Scope,也就是 由定义过程决定 Frame层级
    • Python 调用函数时,会创建新的Frame,一个函数的父Frame由它在哪里定义决定
      • 调用自定义函数时才会创建 Frame,Builtins的方法是不创建Frame的
  • python的特殊字符串

    • f‘It is {word}.’ 使用 word变量替换{word}
    • 'It is {0}'.format(word) 使用word变量替换{0}
  • 调用自定义函数时才会创建 Frame,Builtins的方法是不创建Frame的

  • float('inf') 会返回一个用浮点数表示的正无穷值,可以与其他数值进行比较。

  • isinstance(obj,type)type(obj) == type

    • 前者考虑继承关系,即obj即使不是type但是是type的子类实例也True
    • 后者不考虑继承关系
  • 当子类绑定方法中需要调用基类的绑定方法时,我们需要使用 super().method(args)

    • 不能使用 基类类名,因为是绑定方法,如果用类名我们需要创建一个基类的实例作为第一个参数,但是这样操作的就是基类的实例,而非本实例
    • super()方法不是创建一个新的基类实例而是寻找基类方法并将本实例作为self传过去运行基类的例程,因此操作的是本实例
  • python中对于可迭代对象都具有解包功能

    • list、tuple、range、dict
    • a,b,c = list\tuple\range\dict
      • 注意,解包的变量数和可迭代对象项数要一致
      • dict 直接解包是对 key 解包,而相对 value 解包可以 a,b,c = dict.values()

小窍门


  • 遍历list中所有子串组合 --- 位运算

    • 这个是为了返回和为偶数的子序列的list的函数,当然也可以通过互递归实现 见example里的even_set
      def even_sublist(s):
      """返回s中和为偶数的子序列的list"""
      if not s:
          return None
      result = []
      n = len(s)
      for i in range(1 << n):
          sublist = [s[j] for j in range(n) if (i & (1 << j))]
          if sum(sublist) % 2 == 0 and len(sublist) >= 1:
              result.append(sublist)
      return result
      
  • 递归抽象思想

    • 在 涉及链表、Tree 和 图的问题中,经常会使用递归
    • 在编写递归函数时,我们一定要有抽象思维,明白递归函数是什么作用,把它当成一个效用来看,不要一开始就分析复杂的递归过程,也就是说 将递归函数视作一般流,把递归调用视作效用
    • 实在有问题了再分析,而且也是先分析抽象层面

评论