Python基础17 嵌套函数 函数类型和Lambda表达式 三大基础函数 filter() map() reduce()

  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 仅包含一个条目,则将返回第一项。

 

posted @ 2020-10-11 12:46  想活出点人样  阅读(190)  评论(0编辑  收藏  举报