Week 4
本周学习主要内容包括解析式和生成器表达式,内建函数
哈希(hash):
- 通过哈希函数得到的散列值
- 数据分为可哈希(hashable)类型和不可哈希类型
- 不可变为可哈希;可变为不可哈希(字符串例外)
简单选择排序
- 选择排序:每一趟两两比大小,找出极值病房知道有序区的位置(冒泡法)
核心算法:
- 结果可以升序或降序,默认升序
扩大有序区,缩小无序区
减少了交换次数,提高了效率,性能略好于冒泡法
解析式和生成器表达式(必备技能)
列表解析式
List Comprehension,也叫列表推导式。
语法:
nums = [] #创建一个全新列表,并为其初始化内容 #第一步
for i in range(5): #第二步
nums.append(i+1) #第三步
print(nums)
列表解析式是一种“语法糖”:
##列表解析式/推导式 -- 表达式
[i+1 for i in range(5)] #解析式语法,立即生成一个新列表并填充内容
- [返回值for元素in可迭代对象if条件]
- 使用中括号[],内部是for循环,if条件语句可选
- 立即返回一个新列表
- 编辑器会优化,效率提高,性能也得到优化
- 简化代码增加可读性
- 减少工作量,降低出错率
- 式中不允许出现else,elif
- 只有“一斜到底”的循环可以改造成解析式
生成器表达式
语法:
- (返回for元素in可迭代对象if条件)
- 列表解析式的中括号换成小括号
- 返回一个生成器对象
和列表解析式的区别:
- 生成器表达式是按需计算(懒计算方式/惰性求值,延迟计算),需要时才计算值
- 列表解析式是立即返回值
生成器对象:
- 可迭代对象
- 迭代器(第一个讲到的迭代器!!)
生成器表达式&列表解析式
生成器表达式 | 列表解析式 |
---|---|
延迟计算 | 立即计算 |
返回可迭代对象迭代器 | 返回可迭代对象列表(不是迭代器) |
只能迭代一次 | 可以反复迭代 |
- 内存占用:
但从返回值本身来说,生成器表达式省内存,列表解析时返回新的列表
集合解析式
- {返回值for元素 in可迭代对象 if条件}
- 列表解析式的中括号换成大括号
- 立即返回一个集合
- 注意集合的去重性和内部元素可哈希
字典解析式
- {key:value for元素in可迭代对象if条件}
- 列表解析式的中括号换成大括号,元素构造使用key:value的形式
- 立即返回一个字典
总结:
- 一般来说应该多用解析式,简短高效。但如果过于复杂考虑拆成for循环
- 生成器和迭代器是不同的对象,但都是可迭代对象
- 如果不需要立即获得所有可迭代对象的元素,在Python3中推荐使用惰性求值的迭代器
内建函数
- 标识 id():返回对象的唯一标识,CPython返回内存地址
- 哈希 hash():返回一个对象的哈希值
- 类型 type():返回对象的类型
- 类型转换:
float() int() bin() hex() oct() bool() list(可迭代对象) tuple(可迭代对象) dict(k可哈希) set(可哈希) complex() bytes() bytearray()
- 输入input([prompt]):接受用户输入,返回一个字符串
- 打印 print(*objects,sep=’’,end=’\n’,file=sys.stdout.flush=False):打印输出,默认空格分隔、换行结尾,输出到控制台
- 对象长度 len():返回一个集合类型的元素个数
- isinstance(obj,class_or_tuple):判断对象obj是否属于某种类型或元组中列出的某个类型;isinstance(True,int)
- issubclass(cls,class_or_tuple):判断类型cls是否是某种类型的子类或元组中列出的某个类型的子类;issubclass(bool,int)
- 绝对值abs(x) x为数值
- 最大值max()最小值min():返回可迭代对象中最大或最小值,返回多个参数中最大或最小值
- round(x)四舍六入五取偶,rount(-0.5)
- pow(x,y)等价于x**y
- range:计数器,range(stop)从0开始到stop-1的可迭代对象;range(start,stop[,step])从start开始到stop-1结束,步长为step的可迭代对象
- divmod(x,y)等价于tuple(x//y,x%y)
- sum(iterable[,start]):对可迭代对象的所有数值元素求和;sum(range(1,100,2))
- chr(i):给一个一定范围的整数返回对应的字符
- ord(chr):返回字符对应的整数
- reversed(seq):返回一个翻转元素的列表
- enumerate():
可迭代对象
- 能够通过一次次迭代返回不同的元素的对象:所谓相同不是指值是否相同,而是元素在容器中是否是同一个,例如列表中值可以重复,[‘a’,‘a’],虽然这个列表中有2个元素,值一样但两个’a’是不同的元素
- 可以迭代,但未必有序,未必可索引
- 可迭代对象有:list、tuple、string、bytes、bytearray、range、set、dict、生成器、迭代器等等
- 可以使用成员操作符in、not in:in本质上对于线性数据结构就是在遍历对象
迭代器:
- 特殊的对象一定是可迭代对象,具备可迭代对象的特征
- 通过iter方法把一个可迭代对象封装成迭代器
- 通过next方法,可迭代迭代器对象
- 迭代器对象只能从头到尾迭代一遍
- 生成器对象就是迭代器对象,他是特殊的迭代器对象
Python函数
- Python函数:由若干语句组成的语句块、函数名称、参数列表组成,他是组织代码的最小单元,可以完成一定功能
- 函数作用:
- 结构化编程对代码的最基本封装,一般按照功能组织一段代码
【输入 => 输出】 - 封装的目的为了复用,减少冗余代码
- 代码更加简洁美观可读易懂
- 函数分类:内建函数(直接可用,如max()、reversed()……);库函数(需要加载,如math.ceil()……);自定义函数(使用def关键字定义)
函数定义
def 函数名(参数列表):
函数体(代码块)
[return 返回值]
- 函数名就是标识符,明明要求一样
- 语句话必须缩进,四个空格
- Python中函数若没有return语句,会隐式返回一个None值(Jupyter中被隐去看不到返回结果,容易造成误解)
- 定义中的参数列表称为形式参数,只是一种符号表达(标识符),简称形参
- 定义时,解释器扫过这段代码后,会立即生成一个函数对象,堆中,用标识符add指代该函数对象
- 只需定义一次函数
函数调用
- 函数定义,只是声明了一个函数,它不能被执行,需要调用执行
- 调用的方式,就是函数名后加上小括号,如有必要在括号内填上参数
- 调用时写的参数是实际参数,是实实在在传入的值,简称实参
例. 函数add:
- 定义一个函数add,函数名是add,能接受两个参数
- 该函数计算的结果,通过返回值返回,需要return语句
- 调用时,通过函数名add后加两个参数,返回值可使用变量接受
- 函数名也是标识符
- 返回值也是值(None值)
- 定义需要再调用前,也就是说调用时,已经被定义过了,否则NameError异常
- 函数是可调用对象(callable)
函数参数
函数在定义是要定义好形参,调用时也要提供足够的实参,一般来说形参实参个数要一致,除去可变参数
实参传参方式:(只有两种方式)
传参指调用时传入实际参数
- 位置传参
定义时def f(x,y),调用使用f(1,3,5),按照参数定义顺序传入实参 - 关键字传参
定义时def f(x,y),调用使用f(x=1,y=3,z=5),使用形参的名字来传入实参方式,如果使用了形参名,与顺序无关
这两种传参方式可以混用,但位置传参不能跟在关键字传参之后!!!
形参缺省值:
缺省值也叫默认值,可以在函数定义时,为形参增加一个缺省值,作用为:
- 参数的默认值可以在未传入足够的实参时,对没有给定的参数赋值为默认值(填补作用)
- 参数非常多的时候,并不需要用户每次都输入所有参数,简化函数调用(简化作用)
可变参数:
- 可变位置参数:
- 在形参前使用*表示该形参是可变位置参数,可接受多个实参
- 他将收集来的实参组织到一个tuple中(元组不可变)
- 可变关键字参数:
- 在形参前使用**表示该形参是可变关键字参数,可接受多个关键字参数
- 他将收集来的实参组织到一个dict中(字典可变)
- 有可变位置参数和可变关键字参数
- 可变位置参数在形参前使用一个*(*args)
- 可变关键字参数在形参前使用两个**(**kwargs)
- 可变位置参数和可变关键字参数都可以收集若干个实参,可变位置参数收集成一个tuple对象,可变关键字参数收集成一个dict对象
- 混合使用时普通参数要放在参数列表前面,可变参数放在后面,可变位置参数要在可变关键字参数之前(越复杂越在后)
keyword-only参数:
- 在形参定义时,在一个*之后,或一个可变位置参数之后,出现的参数就已经不是普通的参数了,称为keyword-only参数
- *之后所有普通参数都变成了keyword-only参数
positional-only参数:
- Python3.8之后新增类型
参数规则:
-
参数列表一般顺序是:positional-only参数、普通参数、缺省参数、可变位置参数、keyword-only参数(可带缺省值)、可变关键字参数参数
-
一般形参有五种类型:positional-only参数、普通参数、可变位置参数、keyword-only参数、可变关键字参数参数
参数解构:
- 再给函数提供实参时,可以在可迭代对象前使用*或**来进行结构的解构,提取其中所有元素作为函数的实参
- 使用*解构成位置传参
- 使用**解构关键字传参
- 提取出的元素数目要和参数的要求匹配