1 #函数 2 3 #嵌套函数 4 #和C语言不一样的是,Python可以在函数里面定义函数(这就很魔幻) 5 #那我们来尝试一下 6 7 def get_shuju(a,b,ord): 8 9 def add_sj(a,b): 10 return a+b 11 12 def qiuyu(a,b): 13 return a%b 14 15 def chengfa(a,b): 16 return a*b 17 if(ord==1): 18 return add_sj(a,b) 19 if(ord==2): 20 return qiuyu(a,b) 21 if(ord==3): 22 return chengfa(a,b) 23 #这里我们就定义了一个函数 24 #而且在函数中我们还定义了多个函数进行嵌套 25 print(get_shuju(10,52,2)) 26 #我们这里就可以算出数据的值 27 #可以正常调用在get_shuju函数的定义的函数 28 #那这个函数是否符合作用范围呢? 29 #是否和全局变量和局部变量有一样的性质呢? 30 31 #chengfa(10,2) 32 #我们在函数内定义的函数,在这个函数外是没有办法调用的 33 #那么我们再定义一个全局变量的函数是否会对局部变量函数生效吗? 34 35 def test_2(): 36 print("全局变量") 37 return 0 38 39 def test (): 40 def test_2(): 41 print("局部函数") 42 return 0 43 test_2() 44 return 0 45 46 #这样就建立了两个test_2函数 47 #一个是就全局而言,一个是就函数test而言的 48 test_2() 49 test() 50 #这样就看到了,这里test_2的全局变量并没有覆盖掉test中的test_2 51 #依旧符合翔龙斗不过地头蛇的基本定理 52 def test_3 (): 53 global test_2 54 test_2() 55 return 0 56 #我们也可以通过添加global声明来调用全局的函数test_2 57 test_3() 58 59 ''' 60 def test_4(): 61 def test_2(): 62 print("局部函数") 63 return 0 64 global test_2 65 test_2() 66 return 0 67 ''' 68 #但是我们发现,这里在定义了局部函数test_2以后,又声明global来调用test_2是会冲突的 69 #会直接报错的。 70 ''' 71 def test_4(): 72 global test_2 73 test_2() 74 def test_2(): 75 print("局部函数") 76 return 0 77 return 0 78 ''' 79 def test_4(): 80 global test_2 81 def test_2(): 82 print("我改变了吗?") 83 return 0 84 test_2() 85 return 0 86 87 test_4() 88 test_2() 89 #而根据上面的几个代码的测试我们发现 90 #我们也可以通过先声明这里使用global 的 test_2 91 #然后再定义函数test_2是可以的 92 #但是要注意,如果你这么做了,那么你就改变了全局变量中的test_2函数的内容了 93 94 print("////////////////////////////////////") 95 96 #函数类型 97 #函数和变量一样也是有类型的 98 #Python创建了一个函数类型function 99 #任何一个函数都有函数类型,函数调用的时候就产生了函数类型实例 100 #也就是函数对象 101 #函数类型实例与其他类型实例在使用场合上没有区别 102 103 def function_0(a,b): 104 c=a+b 105 return c 106 #我们先建立一个函数 107 108 f1=function_0(10,20) 109 print(type(f1)) 110 #我们看到这里的类型并不是function,而是int 111 112 def function_1(c): 113 def add(a,b): 114 return a+b 115 def add_2(a,b): 116 return a+a+b+b 117 if c>0: 118 return add 119 else: 120 return add_2 121 f2=function_1(10) 122 f3=function_1(-10) 123 print(type(f2)) 124 print(type(f3)) 125 #这里返还的数据类型就是function类型 126 #而当我们上述设置了f2和f3的时候 127 #f2和f3其实就不是原来的简单变量了 128 #它变成了function函数类型 129 #储存的是不同c值的function_1函数的运算 130 #而这里不同c值的情况对应的是不同的局部函数add 131 #而add函数也是要收录数据的 132 #那么我们就可以直接使用f2和f3来做对应c值情况下的a,b的数据收录 133 134 print("c>0:10+20={0}".format(f2(10,20))) 135 print("c<0:10+20+10+20={0}".format(f3(10,20))) 136 #运行结果完全正确 137 138 print("////////////////////////////") 139 140 #Lambda表达式 141 #Lambda表达式本质上是一种匿名函数 142 #匿名函数也是函数,有函数类型,可以创建函数对象 143 #格式 144 #lambda 参数列表:Lambda体 145 def shuju_2(c): 146 if(c>0): 147 return lambda a,b:a+b 148 else: 149 return lambda a,b:a-b 150 return 0 151 #这里我们就建立了一个含有lambda表达式的代码 152 f4=shuju_2(2) 153 print(f4(10,10)) 154 print(type(f4)) 155 #函数类型变成了Lambda 156 #数据可以正常输出 157 #注意 158 #Lambda只能处理一些简单的数据 159 #而且它不是一个代码块,不能包含多条语句,只能填写一条语句 160 #语句会计算出一个值然后返还给Lambda表达式,但是不需要用return返还 161 162 print("////////////////////") 163 164 #三大基础函数 165 #filter() 166 #它可以对迭代对象的元素进行过滤 167 #基本格式 168 #filter(function,iterable) 169 #function是一个函数,参数iterable是一个可迭代对象 170 #在使用filter()的时候,会遍历iterable,然后元素被一个一个传入function中进行判断 171 #function函数返还布尔值,如果是True就会保存,False就被过滤 172 173 name =["茄子","大司马","海鸥"] 174 print(name) 175 name_filter=filter(lambda n : n.startswith('茄'),name) 176 print(name_filter) 177 #<filter object at 0x0000018739034790> 178 #返还值是这个,为什么呢? 179 print(type(name_filter)) 180 #我们这里就看出来了,name_filter的数据类型是filter 181 #那我们需要将其转换成list类型才能输出 182 print(list(name_filter)) 183 #我们要注意这里用list()来转变,filter本身就是一个可迭代类型 184 #就不需要加上[] ()这样转变了 185 #startswith可以过滤多要求的数据吗? 186 #我们来测试一下 187 name_filter_2=filter(lambda n : n.startswith('茄'and '大'),name) 188 print(tuple(name_filter_2)) 189 #但是这里就只输出了'大司马' 190 name_filter_3=filter(lambda n : n.startswith('茄'and '大'),name) 191 print(list(name_filter_3)) 192 #还是只输出了大司马 193 name_filter_3=filter(lambda n : n.startswith('茄'or '大'),name) 194 print(list(name_filter_3)) 195 #我们由此得出结论 196 #它并不会过滤多要求的元素 197 #并且如果写的and他会以后面那个作为判断标准 198 #如果写or就会以前面的作为判断标准 199 name_filter_3=filter(lambda n : n.startswith('茄'and '大'or'海'and'蛇'),name) 200 print(list(name_filter_3)) 201 202 print("///////////////////////////") 203 204 #map() 205 #映射操作使用map()函数,它可以对迭代对象的元素进行变化 206 #基本格式 207 #map(function,iterable) 208 name_2=["JOJO","Dio","Gaiya"] 209 name_map=map(lambda n:n.lower(),name_2) 210 print(list(name_map )) 211 #这里name_2的所有的字符串的字母都变成小写了 212 213 #但是这里要特别注意 214 #Python这里是不支持流式操作的 215 #就是不同意他在这里链式使用 216 #举例 217 218 name_filter_4=filter(lambda n:n.startswith("J"),name_2) 219 #这样jojo就被保留了 220 #这时候如果我们想进行流式操作 221 name_map_2=map(lambda n:n.lower,name_filter_4) 222 print(list(name_map_2)) 223 #[<built-in method lower of str object at 0x000001C368D3A570>] 224 #这是因为我们这个时候的name_filter_4还是filter类型 225 226 name_filter_4=filter(lambda n:n.startswith("J"),name_2) 227 print(list(name_filter_4)) 228 name_map_2=map(lambda n:n.lower(),name_filter_4) 229 print(list(name_map_2)) 230 #但是这里我们输出的数据就变成了[] 231 #这说明这里流式操作时有问题 232 233 #那我们只能把它写到一个式子里面去了 234 name_map_3=map(lambda n:n.lower(),filter(lambda n:n.startswith("J"),name_2)) 235 print(list(name_map_3)) 236 #这样就完成了 237 #要注意的是,虽然规定了function只能写一条语句,但是我们可以在后面iterable里操作 238 239 print("////////////////////////////") 240 241 #reduce() 242 #聚合操作会将多个数据整合成数据然后输出单个数据 243 #最基础的就是归纳函数reduce() 244 #基本格式 245 #reduce(function,iterable,initializer) 246 #initializer表示初始值 247 248 import functools 249 #调用functools模块 250 aaa=(1,2,3,4,5) 251 aaa_reduce=functools.reduce(lambda i,acc:acc+i,aaa) 252 print(aaa_reduce) 253 #这么我们就算出了aaa中间的数据 254 #先用lambda生成出两个变量,然后做加法,iterable则是aaa来传递参数 255 aaa_reduce_2=functools.reduce(lambda i,acc:acc+i,aaa,100) 256 print(aaa_reduce_2) 257 #而最后一位就是初始值 258 aaa_reduce_2=functools.reduce(lambda i,acc:acc*i,aaa,100) 259 print(aaa_reduce_2) 260 #这说明如果是初始值 261 #第一次的运算操作将会从它开始运算 262 263 #而我们知道 264 #字符串也是可迭代变量 265 #那是不是也可以进行操作呢? 266 267 bbb="卡面来打!kuga!" 268 bbb_reduce=functools.reduce(lambda i,j :i+j,bbb) 269 print(bbb_reduce) 270 #数据没有变化 271 #因为这里只有一个数据 272 bbb_2=("A",1,2) 273 #bbb_2_reduce=functools.reduce(lambda i,j :i+j,bbb_2) 274 #print(bbb_2_reduce) 275 #TypeError: can only concatenate str (not "int") to str 276 #报错显示不能让int和str一起连接计算 277 bbb_3=("A","B","C") 278 bbb_3_reduce=functools.reduce(lambda i,j :i+j,bbb_3) 279 print(bbb_3_reduce) 280 #这里我们就看到它将三个单独的字符串做了加法运算 281 #字符串的加法就是直接链接在一起 282 283 284 #官方解释: 285 #将两个参数的 function 从左至右积累地应用到 iterable 的条目,以便将该可迭代对象缩减为单一的值。 286 # 例如,reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 是计算 ((((1+2)+3)+4)+5) 的值。 287 # 左边的参数 x 是积累值而右边的参数 y 则是来自 iterable 的更新值。 288 # 如果存在可选项 initializer,它会被放在参与计算的可迭代对象的条目之前,并在可迭代对象为空时作为默认值。 289 # 如果没有给出 initializer 并且 iterable 仅包含一个条目,则将返回第一项。