变量和函数的继续讨论
如果函数的内容无global关键字,优先读取局部变量,再读取全局变量。又因为字符串,数字,元组是不可变类型,改变它们需要重新赋值,以赋值马上在局部变成了局部变量。所以这三种在局部中无法更改 ,而其余可变类型不需要赋值用方法就可改变。所以
可以在局部中修改全局变量
如果在前面声明 global 变量 则这个局部所用的这个变量都为全局变量
全局变量都应该大写,局部变量小写
name = "刚娘"
def test1():
name = "haha1"
def test2():
nonlocal name #nonlocal 上一级的变量 #如果多层嵌套,一层没有会自动去它上一层找,再没有去更上层找
name = "冷静"
test2()
print(name)
print(name)
test1()
print(name)
python程序是从上而下来执行程序,和linux中firewalld一样。 定义函数就相当于赋值,读取到内存中,所以要注意执行中,有需要的变量应该在其上层,防止执行时候,找不到。
递归:
在函数里面调用自身函数
注意事项:
1 必须要有明确的结束条件
:因为递归在函数里面再执行本身函数,又回到函数开头,相当于死循环,在递归当中,只要一出现本身函数,就会马上回到起始函数开头(进入下一层) 就相当于一碰就滑,里面要有防滑点(打断的条件)
在while 循环中,我们用break 打断(continu是直接回到开始再循环) ,而在递归中,我们必须要有一个去终止循环的条件,去终止它,濡染一直循环就会沾满内存报错。
2 每次深入一层递归时,问题规模应该递归减少
3 递归效率不高
函数有自己的作用域,不管在哪个地方调用,它还是会去找内存地址中原来函数,无法影响他的作用域。
匿名函数
lambda x:x+1 #就x 形参 x+1 return的值 就相当于 def test(x): return x+1
print(lambda x:x+1) #内存地址 lambada就相当于建了一个没有变量名的函数
test = lambda x:x+1 #使用变量 保存lambda创建的函数
print((lambda x:x+1)(10)) #直接lambda x:x+1(10) 的话系统认为返回值是x+1(10),变成宁外一个函数
x =lambda x:x+1(10)
(#lambda 既然匿名函数,就不要想后面加入复杂逻辑运算。:后面应该直接加入简单运算结果 return的值
#匿名函数一般配合定义的函数使用,不用赋值存着,用完即释放内存,销毁(这是它的最大优点))
函数式编程
先用数学逻辑去表达出来 ,然后用pyehon中函数去实现。 python 不是严格意义上的函数式编程语言 几种主要函数式编程语言 hashell clean 等
1. 函数即变量 2.函数中不能赋值去存储数据状态
高阶函数
把函数当作一个参数(函数名)传入另一个函数或者return 中有函数 ,这样的函数叫高阶函数, 装饰器就是高阶函数
xx = [19,34,3,7,5] #lanbda x:x+1
def ff_1(x):
return x+1
def ff_2(x):
return x-1
def ff_3(x):
return x**2
def ff_4(x):
return x/2
def test(fangfa,x):
a =[]
for i in x:
a.append(fangfa(i))
return a
print(test(ff_3,xx))
#这个函数典型高阶函数,把函数名当作参数传入另一个参数 ,这个函数实现了,我传入一个可迭代类型的数据(x),后面怎么处理数据要看fangfa传入的是什么
函数,改变fangfa,就能改变处理x参数的程序,实现了好扩展。
1 map() #函数是python中的内置函数,属于高级函数
map(lambda x:x+1,xx) map(ff_1,xx)
#实现了上面的那么多代码的功能,,map内置了for循环后一个参数,每得到一个值给前一个参数传入,但是注意,得到的值将会是
#生成器(生成器就是一种介于程序和数据之间的介质,你不碰它,就是个介质性质在那放着,你一碰他,就输出原本要的结果值)
2 filter
people = ["huangjian","sb_panpan","sb_tancheng","maozi","xisao"]
print(list(filter(lambda x: "sb" not in x ,people)))
people =[{"name":"alex","age":1000},
{"name":"wupei","age":10000}
]
print(list(filter(lambda x:x["age"] != 10000, people)))
#filer的主要是前面参数的函数判断是否成立,成立即(True)则留下后面参数,不成则丢弃 而map不是判断前面函数成立否去判断去留后面for参数的去留
#amp 和 filter 结果都是生成器
3 from functools import reduce #reduce函数不能直接用,要去 functools模块中调用它
num = [1,3,5,7,9,100]
reduce(lambda x,y:x+y,num,z=None) #z为开始的值,不填值默认第一个,填了就以这个元素去开始代入前面函数执行合并操作 至于合并是增加,减少还是怎么样,要看前面的函数
reducez执行结果直接返回一个值 reduce说白了就是一个合并操作
尾递归 (基本上用不到)
在函数最后一步(注意是最后一步)进入递归,进入下一层。此时函数下面没有等待执行的程序,当前层就会释放,不会记住(没有栈)。函数执行结果完整个函数就完了。
根据以上原理,如果是普通递归,函数每进一层,内存就要保存一层的状态(记录栈),层数多了,数据拥挤,就导致递归效率低。
常见内置函数
abs() 取绝对值
内置方法:
py自带内置的一些函数,不需要轮子调用。
#a = -123
#print(abs(a))
#abs #取绝对值
#all #针对可迭代对象,如果每次取值都不是空值,则返回true,反之返回false
#print(all((3,4,1,-1)))
#any #针对可迭代对象,只要一次取值存在,,则返回true,反之返回false
#print(any((0,1)))
#print(bin (10))
#print(bin(64))
#bool() #布尔 为不为空值 0 或者没有值
#bytearray # byte 类型的数据原本不可改,只能生成一个新数据。但是使用bytearray后,能进行二进制更改
#a = bytearray("abcd",encoding = "utf-8") #字符串"abcd"变成字节类型
#print(a[0]) #打印的是a在assci的位子
#a[0] = 110 #把a 变成ascii 对应的110号位子的字符
#print(a) # a变成了n
#a = "hahah"
#b = bytes(a,encoding="utf-8")
#print(type(b)) #bytes把其他类型变成二进制类型
#callable() #里面写函数或者类, 可调用的东西
#ord("a") chr(97) #ord是查看字符的ascci码里面的编号,chr刚好相反
#compile 就是一个编译的命令,先把代码变成字符串,然后
#a = "for i in range(10) : print(i)" #执行compile命令编译成相映的执行程序存在变量中,
#b = compile(a,"","exec") #然后可以直接执行程序此变量
#dict() #字典
#dir #查看有什么方法
#divmod(5,2) #两数向除的商个余数
#enumerate() #把一个迭代对象变成下标和参数一组的元组形势
#float() #浮点数
#format #字符串的格式化
#frozenset #把集合变成不可变的集合
#haha = 213154
#print(globals()) # 返回当前程序的全局变量
#print(locals) #返回当前执行程序的同一级别变量(局部变量)
#hash() #把要存的一些东西通过一定的算法映射成数字,使之
# 要取的东西能快速找出,能hash的都是不可变数据类型,且hash处理的数据不能反过来通过hash数据推出真实数据
#hex() #把数字转成16进制
#oct() #转8进制
#bin #变成2进制
#id() #返回内存地址 #input #等待输入 int() #变成整数类型
#a = "hahha"
#print(isinstance(a,list)) #判断是否是什么类型数据
#locals() #只显示局部变量
globals() #显示当前程序的全局变量,不显示局部变量
#lambda(i:i**2 ,range(10)) # 匿名函数,函数很简单(三维),而且只调用一次,就用匿名函数
#def square(x) :
# return x ** 2
#print(pow(2,8)) #多少次方
#round(数字,数字) #保留小数点后面几位
#a = [1,2,3]
#b = ["a","b","c"]
#for i in zip(a,b):
# print(i) #zip 像拉链一样把连个列表一一对应
NAME = eval("['huang','jian']") #提取字符串中的数据类型和字符串中数学运算结果
print(eval("(1+2)*3"))
max
l =[(5,'e'),
(1,'b'),
(3,'a'), ('t','a') #会报错,首先max后面for循环对象依次取元素比较,都是元组,无法比较大小,取里面第一个元素比较,5,1,'t',4,类型不同,无法比较字符串和数字大小,所以报错
(4,'d')]
print(max(l))
ll = ['a10','b12','c10']
print(max(ll)) #max后面接可迭代对象,依次进行取值(for循环)比较大小,如果元素整体不能比较(同类型数据,不同类型数据比较不了,这里要注意,for循环和再取值的时候,数据类型要一致,不然会报错),就找你们子元素继续做比较(a,b,c),把最大的写出来 。
#max无法比较字典类型,如果for循环得到的元素是字典,无法比较将会报错。
ttt = [{'name':'huangjian','age':18},
{'name':'panpan','age':28}]
print(max(ttt,key=lambda x:x['age'])) #for循环后得到字典,字典进行比较,字典不能比较,此时用到max函数里面的方法key,后面接一个定义的函数
rrr = {'ege1':12,'age2':18,'fge3':25,'gge4':30,'ktgrt':77,'test':348}
print(zip(rrr.values(),rrr.keys()))
sorted() #排序,就是比较大小,然后排列顺序,很max很像
print(sorted(lll,key=lambda x:x['age']))
sum #求和 后面接可迭代对象,且出来元素必是int或者float类型
print(sum([1,2,3]))
print(sum({1,2,3}))

浙公网安备 33010602011771号