Week3
1 函数基本语法及特性
1.1 定义函数
def 函数名(参数1,参数2,参数3,...): '''注释''' #函数体 return #返回值
函数名() #调用函数
函数特性:
- 减少重复代码;
- 使程序变的可扩展;
- 使程序变得易维护。
定义函数的三种形式:无参、有参、空函数。
函数的使用原则:先定义后调用。
1.2 函数的返回值
- 无return->None;
- return1个值->返回1个值;
- return逗号分隔多个值->元组。
ps.什么时候该有返回值?
调用函数,经过一系列的操作,最后要拿到一个明确的结果,则必须要有返回值,通常有参函数需要有返回值。
什么时候不需要有返回值?
调用函数,仅仅只是执行一系列的操作,最后不需要得到什么结果,则无需有返回值,通常无参函数不需要有返回值。
1.3 函数的参数
1.3.1 形参VS实参
形参即变量名,实参即变量值。
1.3.2 具体应用
1、位置参数:按照从左到右的顺序定义的参数。
位置形参:必选参数
位置实参:按照位置给形参传值
2、关键字参数:按照key=value的形式定义的实参。
无需按照位置为形参传值
注意的问题:
1. 关键字实参必须在位置实参右边
2. 对同一个形参不能重复传值
3、默认参数:形参在定义时就已经为其赋值
可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参)。
注意的问题:
1. 只在定义时赋值一次
2. 默认参数的定义应该在位置形参右边
3. 默认参数通常应该定义成不可变类型
4、可变长参数: 可变长指的是实参值的个数不固定。
注意的问题:
1. *args 会把多传入的参数变成一个元组形式
2. **kwargs 会把多传入的参数变成一个dict形式
3. *args 传值为多个位置参数,**kwargs 传值为多个关键字参数,因此**kwargs必须定义在**args右边
4. 实参可以按位置和按关键字两种形式定义
def foo(x, y, *args): print(x, y) print(args) foo(1, 2, 3, 4, 5) def foo(x, y, *args): print(x, y) print(args) foo(1, 2, *[3, 4, 5]) def foo(x, y, z): print(x, y, z) foo(*[1, 2, 3])
def foo(x, y, **kwargs): print(x, y) print(kwargs) foo(1, y=2, a=1, b=2, c=3) def foo(x, y, **kwargs): print(x, y) print(kwargs) foo(1, y=2, **{'a': 1, 'b': 2, 'c': 3}) def foo(x, y, z): print(x, y, z) foo(**{'z': 1, 'x': 2, 'y': 3})
def info(name,sex,*args,age=1,**kwargs): print(name) print(sex) print(args) print(age) print(kwargs) return 0 info('zhouxy','f',1,2,3,age=18,address='CN') info('zhouxy','f',*[1,2])
1.4 局部变量VS全局变量
在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
school = '深圳大学' # 全局变量 def change_school(school_name): school = '育才中学' # 局部变量 print(school) change_school(school) print(school)
school = '深圳大学' # 全局变量 def change_school(school_name): global school # 声明,参数不能与变量同名 school = '育才中学' # 局部变量 print(school) change_school(school) print(school)
classmate_list = ['panjq','lijm','caiyq'] def change_classmate_list(classmate): '''改同学名''' classmate_list[2] = 'zhouxy' #列表,字典,集合,类都可以在局部变量修改全局变量 print(classmate) change_classmate_list(classmate_list) print(classmate_list)
2 递归函数
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
递归特性:
- 必须有一个明确的结束条件;
- 每次进入更深一层递归时,问题规模相比上次递归都应有所减少;
- 递归效率不高,递归层次过多会导致栈溢出。
def add(n): n=n+1 print(n) if n<999: #最大递归次数999 add(n+1) add(0)
3 函数式编程
Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。
"函数式编程"是一种"编程范式"(programming paradigm),也就是如何编写程序的方法论。
4 高阶函数
def add (x,y,f): return f(x)+ f(y) res = add(-1,3,abs) print(res)
5 内置函数
abs(number) : 返回一个数的绝对值
all(iterable) : 如果所有iterable的元素均为真则返回True,否则返回Fasle
any(iterable) : 如果有任一iterable的元素为真则返回True,否则返回False
bool(object) : 返回True或False,取决于object的布尔值
bin(number) : 将十进制数字转为二进制(?)
byrearray(source,encoding) : 字符串可通过字节码进行修改(?)
callable(object) : 检查对象是否可调用
chr(number) : 返回ASCII码为给定数字的字符
ord(char) : 返回给定单字符的ASCII值
dict([mapping-or-sequence]) : 构造一个字典,可选择从映射或键值对组成的列表构造
dir([objecy]) : 列出给定对象的(大多数)特性,或当前可见作用域的(大多数)名称的列表
divmod(a,b) : 返回(a/b,a%b)
enumerate((iterable) : 对iterable中的所有项
eval(string) : 将字符串转化为字典
filter(function,sequence) : 返回从给定序列中函数返回真的元素的列表
calc = filter(lambda n:n>3,range(5)) #迭代器 for i in calc: print(i)
map(function,sequence,...) : 创建有给定函数function应用到所提供列表sequence每个项目时返回的值组成的列表,或相当于列表生成式
res = map(lambda i:i*2,range(5)) for i in res: print(i)
reduce(function,sequence[,initializer]) : 对序列的所有渐增地应用给定的函数,使用累积的结果作为第一个参数,所有的项作为第二个参数,可选择给定起始值initializer
import functools mul = functools.reduce(lambda x,y:x*y,range(1,5)) #阶乘 print(mul)
float(object) : 将字符串或者数值转换为float类型
frozenset([iterable]) : 创建一个不可变集合
globals() : 返回表示当前作用域(全局)的字典
locals() : 返回表示当前局部作用域的字典
id(object) : 返回内存地址
int(object) : 将字符串或者数字转换为整数
isinstance(object,classinfo) : 检查给定的对象obejct是否是给定的classinfo值的实例,classinfo可以是类对象,类型对象或者类对象和类型对象的元组
iter(object) : 返回一个迭代器对象
len(object) : 返回给定对象的长度(项的个数)
list([sequence]) : 构造一个列表
long(object) : 将字符串或者数字转换成长整型
max(object1,[object2,...]) : 如果object1是非空序列,则返回最大的元素,否则返回所提供参数的最大值
min(object1,[object2,...]) : 如果object1是非空序列,则返回最小的元素,否则返回所提供参数的最小值
oct(char) : 将整型整数转换为八进制表示的字符串
pow(x,y) : 返回x的y次方
round(float[,n]) : 将给定的浮点四舍五入,小数点后保留n位
set(iterable) : 返回从iterable生成的元素集合
sorted(iterable) : 从iterable的项目中返回一个新的排序后的列表
a = {6:2,8:0,-1:9,4:4} print(sorted(a.items())) print(sorted(a.items(),key=lambda x:x[1]))
str(object) : 返回表示给定对象object的格式化好的字符串
sum(seq[.start]) : 返回添加到可选参数start(默认为0)中的一系列数字的和
tuple(sequence) : 构造一个元组
type(object) : 返回给定对象的类型
zip(sequence1,...) : 返回元组的列表,每个元组包括一个给定序列中的项。返回的列表的长度和所提供的序列的最短长度相同
a = [1,2,3,4] b = ['a','b','c'] for i in zip(a,b): print (i)
内置参数详解:https://docs.python.org/3/library/functions.html?highlight=built#ascii
6 practice
# 1、写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成批量修改操作 def change_file(filename,old,new): f = open(filename,'r',encoding='utf-8') f_new = open('filename.bak','w',encoding='utf-8') for line in f: # 循环旧文件 if old in line: line = line.replace('old','new') f_new.write(line) f_new.close() f.close() change_file('1','old','new')
#2、写函数,计算传入字符串中【数字】、【字母】、【空格】 以及 【其他】的个数 def calc(str): res= { 'num': 0, 'alpha': 0, 'space': 0, 'other': 0 } for i in str: if i.isdigit(): res['num']=res['num']+1 elif i.isalpha(): res['alpha']=res['alpha']+1 elif i.isspace(): res['space']=res['space']+1 else: res['other']=res['other']+1 print(res) calc('abcd 1231 ///122vv ')
# 3、写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。 def judge(object): if len(object)>5: print('yes') else: print('no') return 0 judge('123456') judge([1,23,45]) judge((4,5,6,7,8,9,0))
#4、写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。 def new_judge(object): if len(object)>2: new_object= object[0:2] return new_object else: return object a=new_judge([[1,2],{'b':2},{'c':3},'d']) print(a) b=new_judge([1,2]) print(b)