zoukankan      html  css  js  c++  java
  • 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 仅包含一个条目,则将返回第一项。
    悟已往之不谏,知来者之可追
  • 相关阅读:
    脏数据或者场景考虑不全面引发的生产问题
    框架那些事
    RMI远程方法调用和rpc远程过程调用
    如何提高开发效率
    什么是RPC
    TCP/IP协议和HTTP协议
    apache常见错误:VC运行库(找不到 VCRUNTIME140.dll)
    Apache报错:无法使用可靠的服务器域名
    Apache2.4 下载和安装
    Navicat Premium 15.0.17 破解激活(DFoX 注册机)
  • 原文地址:https://www.cnblogs.com/ljh-study/p/13797014.html
Copyright © 2011-2022 走看看