python 学习笔记4:
序列
列表、元组和字符串都属于序列:
—可以索引
—索引值从0开始
—可以切片
—有共同操作符
序列常见BIF
list() #生成一个空列表
list(iterable) #将一个迭代器转化为列表
tuple()
str()
len(sub) #返回sub的长度(元素个数)
max(sub) #返回sub中的最大值,数据类型要一致
min(sub) #返回sub中的最小值
sum(sub) #返回sub中的总和
sum(sub,a) #将sub的总和与a相加返回
sorted(sub) #将sub从小到大排序
reversed(sub) #将sub索引值翻转,返回一个iterable,原sub不变
enumerate(sub) #将sub的索引值和值组合成元组,返回一个iterable
zip(sub1,sub2) #将sub1和sub2的各个元素组合成元组,返回一个iterable
函数
1、创建
def my_function(): #不含参函数
"返回2" #函数文档
return 2
def my_function2(name='deer'): #name为形参,'deer'为默认参数,为形参的初值
print('Hello '+name+'!')
return ['Hello',name,'!']
def my_function3(a,b,*c): c为收集参数,往后的参数(关键字参数除外)全部用一个元组打包给c
print(a,b,c)
2、调用
a = my_function() #a = 2
my_function2('John') #'John' 为实参
my_function2(name='John') #关键字参数,更实用
my_function.__doc__ #查看函数文档
help(my_function) #查看函数文档,转义符起作用,更好看
my_dunction3(1,2,3,4,5) #a=1,b=2,c=(3,4,5)
a,b,c = my_function2() #a = 'Hello' , b = 'deer',c = '!'
a = my_function2() #a = ['Hello', 'deer', '!']
3、局部变量
函数中定义的变量只能在函数内部使用,是为局部变量。
在主程序中定义的变量为全局变量,可以在函数中访问,在函数中修改时会创建一个新的与全局变量名字相等的局部变量,不会影响全局变量的值。
globel 全局关键字:
global a #将a变为全局变量,可在函数中改变全局变量
4、内嵌函数
可在函数中定义函数
def my_function1():
def my_dunction2(): #只有在my_function1中才能调用my_function2
5、闭包
如果在一个内部函数里对一个外部作用域(但不是全局作用域)的一个外部变量进行引用,那么该内部函数,包括被引用的外部变量被认为是一个闭包。或者外部函数返回一个内部函数,那这个内部函数被成为闭包
def my_function1(x):
def my_function2(y):
return x * y #此处my_function2调用了x,因此my_function2被认为是一个闭包,但不能修改,修改时会被屏蔽
return my_function2(x + 2)
nunlocal 关键字:把变量强制声明为非局部变量,与global类似,解决修改问题
6、装饰器
不需要改变原函数的任何东西,就能给一个函数添加额外的功能,比如说我们想在print(‘a’)前执行print(‘check’),我们可以写
def B(func):
def inner():
print('b')
func()
return inner
def A():
print('a')
A = B(A)
A()
我们可以用语法糖写法,在函数A前用@B代替A = B(A)语句,达到相同的效果
def B(func):
def inner():
print('b')
func()
return inner
@B
def A():
print('a')
A() #b\n a\n
对于有参数的函数,可以用不定长参数
def B(func):
def inner(*args,**kwargs):
print('b')
func(*args,**kwargs)
return inner
对于有返回值的函数,inner中也要有返回
def B(func):
def inner(*args,**kwargs):
print('b')
res = func(*args,**kwargs)
return res #将调用的返回值返回
return inner
@B
def A(n):
return n + n
如果我们想根据不同的参数改变不同的功能,可以在装饰器外再封装一个函数
def get_char(char): #把参数加在最外层的函数上,根据此参数生成装饰器
def zsq(func):
def inner():
print(char * 20) #根据char的不同可以打印不同的符号
func()
return inner
return zsq #返回由不同参数生成的装饰器
char2 = input('请输入线符号')
@get_char(char2)
def print_content():
print('社会社会')
print_content()
↑装饰器的通用模板
7、lambda 表达式
使用lambda关键字创建匿名函数
function = lambda x : 2 * x + 1 # function = lambda 参数:返回值
function(5) # function(5) == 11
8、两个强大的BIF
①filter(function or None,iterable):过滤
如果是function,则返回function(item)是True的部分,其中item是iterable的元素;如果是None,则返回item是True的部分。最后返回一个迭代器。
list(filter(None,[1,0,True,False])) #[1, True]
list(filter(lambda x : x % 2,range(10))) #[1, 3, 5, 7, 9]
②map():映射
list(map(lambda x : x * 2,range(10))) #[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
9、递归
函数调用自身
设置递归深度:
import sys
sys.setrecursionlimit(200) #设置深度为200层,默认为100层
生成器
一个抽象等级更高的迭代器,打造一个自己的、更复杂的迭代器,省空间
1、创建和访问
将列表推导式中的[]改为()
list1 = [i for i in range(1,999) if i % 2 == 0] #生成一个列表
gene1 = (i for i in range(1,999) if i % 2 == 0) #生成一个生成器
或借助生成器函数(yield)生成
def scqfunc(): #当函数中出现yield时,这个函数就会变成生成器函数
print('a')
yield 1 #yield后为状态值
print('b')
yield 2 #当使用一个next时会运行到下一个yield,即从一个状态值到下一个状态值
print('3')
g = scqfunc() #此处生成生成器g,函数不会执行
print(next(g)) #或g.__next__()
通过for in访问时会将整个函数执行完毕,包括最后一个yield后的语句
2、send()
send中给一个参数,为给上一个yield语句提供返回值,同时运行到下一个状态值,第一次调用必须返回None
3、关闭生成器
将生成器关闭
g.close()
如果生成器中有return语句,只要碰到就会报出异常