常用系统功能:
str = "aBcedf"
l = len(str) #求字符串长度
c = str.count("a") #统计子字符串“a”在str中出现的次数
result1 = str.startswith("abc") #判断原字符串是否是以"abc"开头的
newstr = str.lower() #将其中的大写字母转换为小写
str.replace("def","hello") #将其中的"def"替换为"hello"
index1 = str.find("c") #获取"c"在原字符串中第一次出现的下标,如果查找不到返回-1
index2 = str.index("c") #获取"c"在原字符串中第一次出现的下标,如果查找不到则报错
函数的特殊使用:
变量可以指向函数
- 【abs(-10)是函数的调用,abs是函数本身】
print(abs(-10)) #10
print(abs) #<built-in function abs>
- 【函数本身也可以赋值给一个变量,x = abs(-10)】
x = abs(-10)
print(x) #10
y = abs
print(y) #<built-in function abs>
- 【如果一个变量指向了一个函数,则可以通过该变量调用函数】
y = abs
print(y(-10)) #10
函数名就是变量名,不能给其随意赋值,即变量名尽量不要和函数名重名【abs():可以将函数名abs看成一个变量,它指向一个可以计算绝对值的函数】
abs = 10
pritn(abs(10)) #报错
函数作为参数使用(见后面)
参数的类型:(必要参数、关键字参数、默认参数、不定长参数)
1.必需参数
调用函数的时候,必须以正确的顺序传参,传参的时候参数的数量和类型必须保持一致
#无参的函数
def test1():
pass
#有参的函数
def test2(a):
pass
def test3(a,b,c):
pass
#调用
test1()
test2(10)
test3(10,20,30)
2.关键字参数【作用在实参上】
print(10,20,end = " ") #10,20是参数,end是关键字参数
使用关键字参数允许函数调用的时候实参的顺序和形参的顺序可以不一致,可以根据关键字进行自动的匹配
#关键字参数
def fun1(name,age):
age += 1
print(name,age)
#正常调用函数
fun1("LiSi",10) #LiSi 11
#使用关键字参数调用函数
fun1(name = "LiSi",age = 10)
fun1("LiSi",age = 10)
总结:关键字参数出现在实参中;
关键字参数要么出现在参数列表的末尾【一个或者多个】,要么全部都是关键字参数;
关键字参数的出现,形参可以不用保持一定的顺序
应用场景:python内置的功能,print()
3.默认参数【作用在形参上】
调用函数的时候,如果没有传递参数,则使用默认的
#默认参数【default】
def fun1(name,age = 18):
print(name,age)
fun1("LiSi",20) #LiSi 20
fun1("LiSi") #LiSi 18
fun1(name = "abc",age = 15)
fun1(name = "hello")
注意:默认参数如果不传参,则使用默认值,如果传参,相当于给形参重新赋值;
在使用默认参数的同时,也可以使用关键字参数;
默认参数只能出现在参数列表的最后面
4.不定常参数(可变参数)
可以处理比声明的时候更过的参数 * **
#不定长参数
#1.*:被当做元组处理
def fun1(*num):
print(num)
print(type(num))
fun1(10) #(10,),<class 'tuple'>
fun1(10,20,30,40) #(10, 20, 30, 40),<class 'tuple'>
fun1(10,2,0,True,"abc") #(10, 2, 0, True, 'abc'),<class 'tuple'>
注意:*被当做tuple处理,形参的变量名其实相当于一个元组的引用
传参的时候,实参可以根据需求传任意数量和任意类型的数据
对应的不定长参数只能出现在参数列表的最后面,并且只能出现一个
可以在实参的部分传一个元组,但是,元组被当做一个整体,形成二维元组
#2.**:被当做字典处理,变量名相当于字典
def fun2(**args):
print(args)
print(type(args))
fun2(x1=1,y1=2) #{'x1': 1, 'y1': 2},<class 'dict'>
注意:如果形参列表中出现了**,实参的传递必需以key=value的方式传递参数
实参的参数名可以任意定义,相当于给字典中添加键值对
def fun3(*num,**num1):
print(num,num1)
fun3(10,20,30,x = "zhangsan",y = 1)
#(10, 20, 30) {'x': 'zhangsan', 'y': 1}
注意【混合使用】:**必须出现在形参列表的最后面
函数的返回值:
return的使用,作用将一个函数运算的结果返回,不是必须存在的
1.return返回一个数据(返回给调用者),运行完即表示结束函数,无法执行return语句之后的其他语句
#需求:求任意两个数的和
def myAdd(num1,num2):
total = num1 + num2
return total
print(myAdd(10,20))
2.return返回多个数据,当做元组进行处理
def test1(a,b,c):
return a,b,c
print(test1("abc",10,True)) #('abc', 10, True)
3.在分支语句中使用return,每个分支语句中return不是必须的,如果每个分支都有return,返回的数据类 型可以不一致
#需求:输入两个数,比较两个数的大小,输出较大的一个
def compare(a,b):
if a > b:
return a
elif a< b:
return b
else:
return True
print(compare(10,20))
4.return后面没有任何数据,只有一个作用:结束函数,返回值相当于是None
def test2(a,b):
if a > b:
return
print(test2(10,20)) #None
自定义函数的需要总结:是否需要设置参数【如果有未知项参与运算】;
是否需要设置返回值【函数运算结果是否需要在函数外部使用】;
但凡设计到功能,尽量封装函数
空函数 :一个什么功能都没有实现的函数,借助于pass语句
主函数【main函数】:每个程序的入口,如下:
#空函数
def test():
pass
test()
if __name__="__main__": #__name__指的是系统内置的变量,前后各两个下划线
test() #和上面调用主函数目的一样,在模块中使用
匿名函数:lambda表达式,比def定义的函数简单
将匿名函数赋值给一个变量,然后使用变量调用函数
将有限的逻辑封装到lambda表达式中,一般用来实现比较简单的需求
lambda拥有自己的命名空间,而且不能访问自有参数列表之外的变量
语法: lambda 参数列表:函数体
#匿名函数
#需求:求两个数的和
def total(num1,num2):
return num1 + num2
print(total(10,20)) #30
result = lambda num1,num2:num1 + num2
print(result(10,20)) #30
#匿名函数进行关键字参数传递
g = lambda x,y:x ** 2 + y ** 2
print(g(2,3)) #13
print(g(x=2,y=3)) #13
#匿名函数也可以使用默认参数
g = lambda x = 0,y = 0:x ** 2 + y ** 2
print(g()) #0
print(g(2,3)) #13
print(g(2)) #4
print(g(y=3)) #9
注意:匿名函数本质是一个表达式,并没有名字,想要被调用,只能赋值给一个变量,然后使用这个变量
调用函数【变量当做函数名使用】;
匿名函数也可以使用关键字参数进行参数传递;
匿名函数也可以使用默认参数
函数作为参数使用:
- 变量可以指向函数,函数的参数可以接收变量,那么一个函数可以接收另外一个函数作为参数,这种函数称为高阶函数
def test(x,y,f):
return f(x) + f(y)
print(test(10,-20,abs)) #30
def hello():
print("hello world")
def show(f):
f()
show(hello) #hello world
注意:函数作为参数使用的时候,也需要遵循传参的规则
偏函数: 对函数形式参数做一些控制的函数称为偏函数
通过设定参数的默认值,可以减低函数的调用难度,而偏函数也可以做到这一点
注意:偏函数一般不需要自己定义,直接使用
int(x) #将x转换为整型,当x为字符串时,默认按照十进制输出,有一个默认的base,默认值是10
print(int("123",base = 10)) #123
print(int("123",base=8)) #83,base指的是前面字符串代表哪种进制,输出为10进制形式
print(int("110",base=2)) #6
#需求:如果需要大量输出二进制
def int2(x,base = 2):
return int(x,base)
print(int2("11010")) #26
print(int2("101010")) #42
print(int2("101110")) #46
import functools
#参数1:函数名 参数2:默认参数
int2 = functools.partial(int,base = 2)
print(int2("11010")) #26
print(int2("11010",base = 10)) #11010
要实现上面的需求,系统提供了功能:functools.partial()
对于一个现成的函数,想要更改函数参数的默认值,生成一个新的函数。被生成的函数被称为偏函数
闭包:
- 如果在一个函数内部定义了另外一个函数,外面的函数叫做外部函数,里面的函数叫做内部函数
- 在一个函数的内部定义了另外一个函数,并且外部函数的返回值是内部函数的引用,这样就构成了闭包
- 闭包应用场景:在python中,装饰器
#1.
def outerFunc():
def innerFunc():
print("hello")
return innerFunc
r = outerFunc() #r = innerFunc
print(r)
r() #hello
#2.outer是外部函数,a和b都是外部函数的临时变量
def outer(a):
b = 10
def inner():
#在内部函数中,可以访问外部函数的临时变量
print(a + b)
return inner
#调用:r1中保存了外部函数的返回值,也就是inner的引用【变量】
r1 = outer(4)
#r1()相当于是调用了inner函数
r1() #14
列表生成式:
List Comprehensions,是python内置的用来生成列表的生成式
格式:[生成的元素规律 for循环 判断条件 ]
range():用法:
r = range(1,11)
print(type(r)) #<class 'range'>
print(list(r)) #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(list(range(1,20,3))) #[1, 4, 7, 10, 13, 16, 19]#需求:生成一个列表,【1,4,9,16,25,36】
#法一:
l = []
for i in range(1,7):
l.append(i * i)
print(l) #[1, 4, 9, 16, 25, 36]
#法二:
#格式:[生成的元素规律 for 循环 判断条件]
#1.
l1 = [i * i for i in range(1,7)]
print(l1) #[1, 4, 9, 16, 25, 36]
#需求:生成一个列表[4,16,36,64,100],使用了单层循环
l2 = [i * i for i in range(1,11) if i % 2 == 0]
print(l2) #[4, 16, 36, 64, 100]
#使用嵌套for循环,生成的列表被称为全排列
l3 = [m + n for m in "ABC" for n in "XYZ"]
print(l3)
#for循环可以同时使用两个或者多个变量
d = {"x":"a","y":"b","z":"c"}
for k,v in d.items():
print(k,"=",v) #x = a y = b z = c
l4 = [k + "=" + v for k,v in d.items()]
print(l4) #['x=a', 'y=b', 'z=c']
#将一个列表中的所有字符改为小写,生成一个新的列表
l5 = ["Hello","ABc","fdhf","YU"]
l6 = [a.lower() for a in l5]
print(l6) #['hello', 'abc', 'fdhf', 'yu']
注意:生成一个列表使用了单循环
使用嵌套for循环,生成的列表被称为全排列
for循环可以同时使用两个或者多个变量
列表生成器:generator
- 作用:为了解决快速的生成一批数据,瞬间占用过大的内存
- 工作原理:生成较大的数据的时候,将数据存储到生成器中,当需要数据的时候,渠道生成器中获取
- 定义生成器有两种方式:将列表生成式中的[ ]换成( ),就是一个生成器;通过函数和yeild【让步】生成
- 注意:生成器可以通过next()遍历其中的元素,当所有的元素被获取完成之后,继续调用该功能,则会出现StopIteration错误【异常】
- 总结:每次执行到yeild关键字的时候,则暂停代码的执行,将yeild的后面的值进行返回,代码停止,下次遍历生成器的时候【for和next】,函数生成器中的代码接着原来暂停的位置继续向下执行
#a.
l1 = [i for i in range(1,6)] #列表生成式
print(l1) #[1, 2, 3, 4, 5]
print(type(l1)) #<class 'list'>
l2 = (i for i in range(1,6)) #列表生成器
print(l2) #<generator object <genexpr> at 0x000001BA665AB228>
print(type(l2)) #<class 'generator'>
#生成器的调用
#法一:for循环进行遍历
for i in l2:
print(i)
'''
#法二:通过调用next()进行元素的获取
print(next(l2)) #1
print(next(l2)) #2
print(next(l2)) #3
print(next(l2)) #4
print(next(l2)) #5
'''
#法三:
def test(n):
for i in range(1,n + 1):
yield i #让步,暂停,已经生成了一个生成器保存下来了,此时不执行下一步,通过函数外的next()或者循环可将元素取出,之后接着执行下一步print操作
print(i)
r = test(5)
print(r)
print(next(r))