变量和函数的继续讨论

       如果函数的内容无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}))


posted @ 2020-06-12 20:59  xiaojianfir  阅读(245)  评论(0)    收藏  举报