Python学习日记(八)

作用域

局部变量:

    • 在函数中定义的参数和变量称为局部变量,仅在函数体内有效,出了函数体就无效,在函数外不能访问函数内定义的变量。

 

全局变量:

    • 在函数外定义的变量为全局变量,作用域为整个代码文件,在函数中可访问全局变量;
    • 使用全局变量时要小心,当试图在函数中访问并修改全局变量的值时Python会自动创建一个名字和全局变量一样的局部变量,但是全局变量的值并未改变,且两个变量不会互相影响。可以访问全局变量但不要在函数内部修改全局变量。
    • def discount(price,rate):
          final_price=price*rate
          old_price=50
          print("修改后的old_price1:",old_price)
          return final_price
      
      old_price=float(input("请输入原价:"))
      rate=float(input("请输入折扣率:"))
      new_price=discount(old_price,rate)
      print("修改后的old_price2:",old_price)
      print("打折完的价格是:",new_price)
      请输入原价:100
      请输入折扣率:0.8
      修改后的old_price1: 50
      修改后的old_price2: 100.0
      打折完的价格是: 80.0

 

global关键字:

    • 想要在函数中修改全局变量的值可以使用global关键字
      def discount(price,rate):
          final_price=price*rate
          global old_price
          old_price=50
          print("修改后的old_price1:",old_price)
          return final_price
      
      old_price=float(input("请输入原价:"))
      rate=float(input("请输入折扣率:"))
      new_price=discount(old_price,rate)
      print("修改后的old_price2:",old_price)
      print("打折完的价格是:",new_price)
          
      请输入原价:100
      请输入折扣率:0.8
      修改后的old_price1: 50
      修改后的old_price2: 50
      打折完的价格是: 80.0

 

 

内嵌函数和闭包

内嵌函数:

    • 可以在函数中定义函数;
    • 内部函数整个作用域都在外部函数之内,出了外部函数就不能在外部访问和调用内部函数。
    • >>> def fun1():
      	print("func1正在被调用...")
      	def func2():
      		print("func2正在被调用...")
      	func2()
      
      >>> fun1()
      func1正在被调用...
      func2正在被调用...

       

闭包:

    • 在内部函数里对外部作用域(不是全局作用域)的变量进行引用,内部函数被认为闭包;
    • 在外部也不能调用闭包函数,同时在闭包中也不能修改外部函数变量的值但是可以访问,因为外部函数的变量在闭包的作用域之外,在执行闭包函数时外部函数是被屏蔽起来的,这个时候修改外部函数的变量就会报变量未定义。(类似全局变量和局部变量)
    • >>> def funx(x):
      	def funy(y):
      		return x*y
      	return funy
      >>> i=funx(8)
      >>> i
      <function funx.<locals>.funy at 0x000001B5B3315EE0>
      >>> i(9)
      72
      >>> funx(8)(9)
      72
      
      #不能修改外部变量
      >>> def funx():
      	x=5
      	def funy():
      		x+=3
      		return x
      	return funy()
      
      >>> funx()
      Traceback (most recent call last):
        File "<pyshell#23>", line 1, in <module>
          funx()
        File "<pyshell#22>", line 6, in funx
          return funy()
        File "<pyshell#22>", line 4, in funy
          x+=3
      UnboundLocalError: local variable 'x' referenced before assignment
    • 若要修改外部变量可以把变量存在列表里,因为容器不会屏蔽变量;
    • >>> def funx():
      	x=[5]
      	def funy():
      		x[0]=x[0]+3
      		return x[0]
      	return funy()
      
      >>> funx()
      8

       

    • 还可以使用nonlocal关键字实现外部变量的修改。
      >>> def funx():
      	x=5
      	def funy():
      		nonlocal x
      		x=x+3
      		return x
      	return funy()
      
      >>> funx()
      8

       

 

lambda表达式:

    • 使用lambda表达式可以省下定义函数的过程,使代码更精简,适合简单的脚本编写。
    • >>> lambda x,y:3*x+y
      <function <lambda> at 0x00000195EE5B5A60>
      >>> g=lambda x,y:3*x+y
      >>> g(3,1)
      10

 

介绍两个复杂内置函数(BIF):

filter()(过滤器):

    • 保留重要的东西,过滤无用的多余信息,即过滤掉非True内容,返回一个对象,可用list将对象转化为列表
    • #传入两个参数,一个是函数或none,一个是可迭代的对象,返回一个过滤过的可迭代的对象
      >>> help(filter)
      Help on class filter in module builtins:
      
      class filter(object)
       |  filter(function or None, iterable) --> filter object
       |  
       |  Return an iterator yielding those items of iterable for which function(item)
       |  is true. If function is None, return the items that are true.
       |  
      
          
      >>> def F(x):
      	return x%2
      
      >>> s=filter(F,range(10))
      >>> s
      <filter object at 0x00000195EE5ABFA0>
      >>> list(s)
      [1, 3, 5, 7, 9]
      
      
      上述代码等价于
      >>> list(filter(lambda x:x%2,range(10)))
      [1, 3, 5, 7, 9]

 

map()(映射):

    • 参数和filter()一样,作用是将可迭代序列的每一个数作为函数的参数进行运算加工,直到所有元素都加工完毕,返回加工后的新序列。
      >>> list(map(lambda x:x*2,range(10)))
      [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

 

例题:

1、编写一个函数,判断传入的字符串参数是否为“回文联”

  • 方法一:
    def palindrome(string):
        length = len(string)
        last = length-1
        length //= 2
        flag = 1
        for each in range(length):
            if string[each] != string[last]:
                flag = 0
            last -= 1
        if flag == 1:
            return 1
        else:
            return 0
    string = input('请输入一句话:')
    if palindrome(string) == 1:
        print('是回文联!')
    else:
        print('不是回文联!')
        
    方法二:
    def H(s):
        list1=list(s)
        list2=reversed(list1)
        if list1==list(list2):
            print("是回文")
        else:
            print("不是回文")
    
    s=input("请输入字符串:")
    H(s)

 

2、编写一个函数,分别统计出传入字符串参数(可能不只一个参数)的英文字母、空格、数字和其它字符的个数。

  • #统计一个参数:
    def Count(s):
        x=0
        y=0
        z=0
        k=0
        lx=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
        ly=[' ']
        lz=['0','1','2','3','4','5','6','7','8','9']
        ss=list(s)
        l=len(s)
        i=0
        for i in range(l):
            if ss[i].lower() in lx:
                x=x+1
            elif ss[i] in ly:
                y=y+1
            elif ss[i] in lz:
                z=z+1
            else:
                k=k+1
        print("英文字母个数:%d\n空格个数:%d\n数字个数:%d\n其他字符个数:%d\n"%(x,y,z,k))
    
    
    s=input("请输入字符串:")
    Count(s)
    
    
    #统计很多参数
    def count(*param):
        length = len(param)
        for i in range(length):
            word = 0
            num = 0
            spa = 0
            oth = 0
            for j in param[i]:
                if j.isalpha():
                    word += 1
                elif j.isspace():
                    spa += 1
                elif j.isdigit():
                    num += 1
                else:
                    oth += 1
            print('第 %d 个字符串共有:英文字母 %d 个,数字 %d 个,空格 %d 个,其他字符 %d 个'
                   % (i + 1, word, num, spa, oth))
    
    count('I love fish.com 123', 'I love you', 'you love 123')

 

3、请将下边的匿名函数转变为普通函数?

lambda x:x if x%2 else None

  • def odd(x):
        if x%2:
            return x
        else:
            return None
 
4、用filter()函数和lambda表达式快速求出100以内所有3的倍数?
  • a = list(filter(lambda x:x%3 == 0,range(1,100)))
    print(a)
    
    b = list(filter(lambda x:not(x%3),range(1,100)))
    print(b)
    
    c = list(filter(lambda x:x if x%3==0 else None,range(100)))
    print(c)

 

5、还记得zip吗?使用zip会将两数以元祖的形式绑定在一块(如下代码),但如果我希望打包的形式是灵活多变的列表而不是元祖(希望是[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]这种形式),你能做到吗?(采用map和lambda的表达式)

  • >>> list(zip([1,3,5,7,9],[2,4,6,8,10]))
    [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
    
    list(map(lambda x,y : [x,y],[1,3,5,7,9],[2,4,6,8,10]))
    
       

总结

  • 函数与过程:过程(procedure)是简单的,特殊且没有返回值的;函数(Function)有返回值,Python严格来说只有函数没有过程
  • 返回值可以是一个int类型,可以返回一个列表,可以返回一个元组
  • 局部变量:在局部生效如在函数中定义的变量
  • 全局变量:作用于整个模块。函数内若试图修改全局变量,Python会新建一个同名局部变量用于存储修改值,原全局变量的值不变
posted @ 2022-03-06 17:52  肥余  阅读(94)  评论(0)    收藏  举报