• python 函数练习题


    函数的结构和参数

    定义一个函数
    def len_num(a):
        return len(a)
    b=len_num([123,1,2])#函数名加括号就调用了 
    print(b)
    
    # 结构:
    #def 关键字,定义函数。
    #len_num 函数名:与变量设置相同,具有可描述性。
    #函数体 :缩进。函数中尽量不要出现print
    # return后面是返回值(len(a)) 在函数中遇到return直接结束函数。
        # return 将数据返回给函数的执行者,调用者 len_num()。
        # return 返回单个元素 是返回原有数据类型的形式返回
        # return 返回多个元素 是以元组的形式返回给函数的执行者。
        
    形参的最终顺序为:
    	**位置参数,
    	*args,
    	默认参数,
    	仅限关键字参数,
    	**kwargs
    
    实参角度:
        1. 位置参数 按照顺序,一一对应
        2. 关键字参数, 一一对应
        3. 混合参数:位置参数一定要在关键字参数的前面。
        
    1.万能参数: *args, 约定俗称:args,
        函数定义时,*代表聚合。 他将所有的位置参数聚合成一个元组,赋值给了 args。
    2.**kwargs 仅限关键字参数
        1.函数的定义时: ** 将所有的关键字参数聚合到一个字典中,将这个字典赋值给了kwargs.
        
    1.*在函数的调用时,*代表打散。
        **{'name': '太白'}打散为name='太白' 
        *[1,2,3]打散为1,2,3
    2.函数外:处理剩余元素
        a,b,*c = [1,2,3,4,5]
    

    函数的取值顺序 加载顺序 作用域

    # 内置名称空间:python源码给你提供的一些内置的函数,print input
    python分为三个空间:
        1.内置名称空间(builtins.py)
        2.全局名称空间(当前py文件)
        3.局部名称空间(函数,函数执行时才开辟)
    
    加载顺序:
    内置名称空间 ---> 全局名称空间  ----> 局部名称空间(函数执行时)
    
    取值顺序(就近原则) 单向不可逆
    从局部找时 局部名称空间  ---> 全局名称空间  --->  内置名称名称空间
    
    两个作用域:
        1.全局作用域 :内置名称空间 全局名称空间
        2.局部作用域:局部名称空间(函数等)
    注意
    1.局部作用域可以引用全局作用域的变量
    2.局部作用域不能改变全局变量。 可以使用,不能改变
    3.注意 python中不可以先引用 后定义
    

    函数名的应用

    1.函数名是一个特殊的变量。
    2.函数名指向的是函数的内存地址,加上()就执行这个函数。
    3. 函数名可以作为容器类类型的元素。
    4. 函数名可以作为函数的实参。
    5. 函数名可以作为函数的返回值。
    

    构造函数和析构函数

    构造函数,用于创建对象的函数。
    析构函数,用于销毁对象的函数。
    
    class Foo(object):
    	def __new__(self,*args,**kwargs): # 构造函数
    		pass 
    	
    	def __del__(self,*args,**kwargs): # 析构函数
    		pass 
    obj = Foo()
    del obj
    

    重写和重载的区别?

    class Foo(object):
    
    	def f1(self,int a1):
    		return 123
    		
    	def f1(self,string a1):
    		pass
    		
    重载,函数名相同而参数类型/个数/返回值不同。
    class Foo(object):
    	def f1(self):
    		print(123)
    		
    class Bar(Foo):
    	def f1(self):
    		print(666)
    		
    重写,在子类中对父类中的方法进行重写。
    

    什么是接口?

    定义一个接口对继承类进行约束,接口里有什么方法,继承类就必须有什么方法,接口中不能任何功能代码
    
    
    强制约束
    抽象类,可以说是类和接口的混合体,既可以定义常规方法,也可以约束子类的方法(抽象方法)
    

    lambda表达式格式以及应用场景?

    匿名函数:为了解决那些功能很简单的需求而设计的一句话函数 与内置函数结合
    函数名 = lambda 参数 :返回值
    
    1.参数可以有多个,用逗号隔开
    2.匿名函数不管逻辑多复杂,只能写一行,且逻辑执行结束后的内容就是返回值
    3.返回值和正常的函数一样可以是任意数据类型
    
    lambda 表达式
    temp = lambda x,y:x+y
    print(temp(4,10))   # 14
    
    可替代:
    def foo(x,y):
        return x+y
    print(foo(4,10))    # 14
    
    和内置函数结合
    1.min max()可以加功能
    2.reversed() 将一个序列翻转
    3.sorted排序函数 可以加key
    4.map对元素进行映射
    5.filter筛选过滤 返回迭代器
    

    *arg和**kwarg作用

    *args代表位置参数,它会接收任意多个参数并把这些参数作为元祖传递给函数。
    **kwargs代表的关键字参数,返回的是字典,位置参数一定要放在关键字前面
    

    Python垃圾回收机制?

    1.引用计数
    引用计数法有很明显的优点:
        对象有确定的生命周期
        易于实现
        原始的引用计数法也有明显的缺点:
        维护引用计数消耗资源,维护引用计数的次数和引用赋值成正比,而不像mark and sweep等基本与回收的内存数量有关。
        无法解决循环引用的问题。A和B相互引用而再没有外部引用A与B中的任何一个,它们的引用计数都为1,但显然应该被回收。
        为了解决这两个致命弱点,Python又引入了以下两种GC机制。
    
    2.标记清除
    	标记-清除”法是为了解决循环引用问题。可以包含其他对象引用的容器对象
    
    3.分代回收
    	Python默认定义了三代对象集合,索引数越大,对象存活时间越长
    

    列举常见的内置函数

    1.abs()  print(abs(a))  #输出3
    返回数字的绝对值
    
    2.all()     此函数用于判断给定的可迭代参数 iterable 中的所有元素是否都不为 0、都不为False 或者iterable都 为空,如果是返回 True,否则返回 False。
    3.any()     函数用于判断给定的可迭代参数 iterable 是否全部为空对象,如果都为空、都为0、或者都为false,则返回 False,如果不都为空、不都为0、不都为false,则返回 True。
    
    3.print()
    print函数是你学Python接触到的第一个函数,它将对象输出到标准输出流,可将任意多个对象打印出来
    
    4.isinstance()
    可以用 isinstance 函数判断某个对象是否属于某个类的实例,函数的定义
    
    range()
    range函数是个工厂方法,用于构造一个从[start, stop) (不包含stop)之间的连续的不可变的整数序列对象,这个序列功能上和列表非常类似,函数定义:
    
    enumerate()
    用于枚举可迭代对象,同时还可以得到每次元素的下表索引值,函数定义:
    
    len()
    
    zip()
                          
                          
    sep 设定分隔符。
    print(1, 2, 3, sep='|')
    end去除默认换行
    print(1, 2, end=' ')
    abs() 获取绝对值
    print(abs(-10))
    sum() 数字相加求和
    # sum() 数字相加求和 会for循环里面元素 必须里面都是由int组成 注意列表 sum(iterable,)
    print(sum([1, 2, 3, 4], 100))
    min max()可以加功能
    # min 可以加功能 key 与匿名函数结合
    # min 可以加功能
    # print(min([22, 11, 45, 2]))
    # l1 = [(73, 'alex'), (35, '武大'), (18, '太白')]
    # print(min(l1,key=lambda x: x[0]))
    # print(min(l1,key=lambda x: x[0])[0])
    # 第一步 循环遍历l1 将里面的元素以形参的方式传给匿名函数得到返回值
    # 第2步  利用内置函数比较返回值 得到想要的结果,在将传进去的元素返回
    reversed() 将一个序列翻转
    # reversed() 将一个序列翻转, 返回翻转序列的迭代器 reversed 示例:
    # l = reversed('123')  # l 获取到的是一个生成器 注意字符串转list会分隔
    # print(list(l))
    sorted排序函数 可以加key
    # lst = [{'id': 1, 'name': 'alex', 'age': 18},
    #        {'id': 2, 'name': 'wusir', 'age': 17},
    #        {'id': 3, 'name': 'taibai', 'age': 16}, ]
    # # 按照年龄对学生信息进行排序
    # print(sorted(lst, key=lambda e: e['age']))
    l = ['班级24','班级15','班级3','班级5','班级25']#,按照数字的顺序从大到小排序,不改变原列表,请以最少代码量实现。(3分)
    print(sorted(l, key=lambda e: int(e[2:]),reverse=False))
    map对元素进行映射
    # map(function,iterable) 可以对可迭代对象中的每一个元素进行映射,分别取执行function
    # 计算列表中每个元素的平方,返回新列表
    # lst = [1,2,3,4,5]
    # def func(s):
    #     return  s*s
    # mp = map(func,lst)
    # print(mp)#对象
    # print(list(mp))
    # # 改写成lambda
    # print(list(map(lambda s:s*s,lst)))
    zip() 拉链方法
    # zip() 拉链方法。函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,
    # 然后返回由这些元祖组成的内容,如果各个迭代器的元素个数不一致,则按照长度最短的返回
    # lst1 = [1,2,3]
    # lst2 = ['a','b','c','d']
    # lst3 = (11,12,13,14,15)
    # for i in zip(lst1,lst2,lst3):
    #     print(i)
    filter筛选过滤 返回迭代器
    filter筛选过滤 返回迭代器
    ls = filter(lambda e:e['age'] > 16,lst)
    

    列表推导式与生成器推导式

    print([ i % 2 for i in range(10) ])  # [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
    print([ i  for i in range(10) ])     # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    print([ 10 % 2])   # [0]
    # %是个运算符。
    
    print(( i % 2 for i in range(10) ))
    #  <generator object <genexpr> at 0x00000000020CEEB8> 生成器
    # 在Python中,有一种自定义迭代器的方式,称为生成器(Generator)。
    # 定义生成器的两种方式:
    # 1.创建一个generator,只要把一个列表生成式的[]改成(),就创建了一个generator:
    # generator保存的是算法,每次调用next(),就计算出下一个元素的值,直到计算到最后一个元素,
    没有更多的元素时,抛出StopIteration的错误。
    # 2.定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,
    而是一个generator
    

    def func(a,b=[]) 这种写法有什什么坑?

    def func(a,b = []):
        b.append(1)
        print(a,b)
    
    func(a=2)
    func(2)
    func(2)
    
    
    '''
        2 [1]
        2 [1, 1]
        2 [1, 1, 1]
        函数的默认参数是一个list 当第一次执行的时候实例化了一个list 
        第二次执行还是用第一次执行的时候实例化的地址存储 
        所以三次执行的结果就是 [1, 1, 1] 想每次执行只输出[1] ,默认参数应该设置为None
    

    如何在函数中设置一个全局变量

    x = 2
    def func():
        global x
        x = 1
        return x
    func()
    print(x)  # 1
    

    简述 生成器、迭代器、可迭代对象 以及应用场景?

    可迭代对象
        1.可以进行循环更新的一个实实在在值。
        2.如何判断一个对象是否是可迭代对象: 利用内置函数:dir()可以查看对象内部方法
        3.有__iter__方法的对象,都是可迭代对象。
        4.str,list set tup 逗是可迭代对象
            print('__iter__' in dir(str))#True
        ps dir()函数可以获取对象所有方法
    
    迭代器
        1.可更新迭代的工具
        2.在python中,内部含有'__iter__'方法并且含有'__next__'方法的对象就是迭代器。
        3.迭代器可以迭代取值。利用next()进行取值(节省内存)或者转为list 元祖等等取值
        4.一个next()取一个值 且会记录位置 迭代器一条路走到底,不走回头路。
        5.取完了再next()会报错(StopIteration) 我们可以用try处理 万能异常(Exception)
        
    可迭代对象转化成迭代器
        利用内置函数iter()
        l1=[1,2,3]
        obj = iter(l1)
        object.__iter__()
    
    1.可迭代对象是一个操作方法比较多,比较直观,存储数据相对少(几百万个对象,8G内存是可以承受的)的一个数据集。
    2.当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。
    3.是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。
    4.当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。
    
    生成器
    1.将return换为yield就是生成器函数
    2.只要函数中出现了yield那么他就不是函数,它是生成器函数。
    3.不结束函数,对应着给 next 返回值(多个值通过元组的形式返回)。 会记录位置
    4.生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
    

    装饰器

    装饰器:
    能够在不修改原函数代码的基础上,在执行前后进行定制操作,闭包函数的一种应用 不修改被修饰函数的代码
    
    
    场景:
       - flask路由系统
       - flask before_request
       - csrf
       - django内置认证
       - django缓存
    # 手写装饰器;
    import functools
    def wrapper(func):
       @functools.wraps(func)  #不改变原函数属性
       def inner(*args, **kwargs):
          #执行函数前
          return func(*args, **kwargs)
          #执行函数后
       return inner
    1. 执行wapper函数,并将被装饰的函数当做参数。 wapper(index)
    2. 将第一步的返回值,重新赋值给  新index =  wapper(老index)
    @wrapper    #index=wrapper(index)
    def index(x):
       return x+100
    

    用Python实现一个二分查找的函数。

    二分查找算法:简单的说,就是将一个列表先排序好,比如按照从小到大的顺序排列好,当给定一个数据,比如3,查找3在列表中的位置时,可以先找到列表中间的数li[middle]和3进行比较,当它比3小时,那么3一定是在列表的右边,反之,则3在列表的左边,比如它比3小,则下次就可以只比较[middle+1, end]的数,继续使用二分法,将它一分为二,直到找到3这个数返回或者列表全部遍历完成(3不在列表中) 
    
    优点:效率高,时间复杂度为O(logN); 
    缺点:数据要是有序的,顺序存储。
    
    li = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
     
    def search(someone, li):
        l = -1
        h = len(li)
     
        while l + 1 != h:
            m = int((l + h) / 2)
            if li[m] < someone:
                l = m
            else:
                h = m
        p = h
        if p >= len(li) or li[p] != someone:
            print("元素不存在")
        else:
            str = "元素索引为%d" % p
            print(str)
     
    search(3, li)  # 元素索引为2
    

    谈谈你对闭包的理解?

    ef foo():
        m=3
        n=5
        def bar():
            a=4
            return m+n+a
        return bar
      
    >>>bar =  foo()
    >>>bar()
    
    种内部函数可以使用外部函数变量的行为,就叫闭包。或者有自由变量
    
    

    是否使用过functools中的函数?其作用是什么?

    用于修复装饰器  flask源码里面有用到
    
    import functools
     
    def deco(func):
        @functools.wraps(func)  # 加在最内层函数正上方
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)
     
        return wrapper
     
     
    @deco
    def index():
        '''哈哈哈哈'''
        x = 10
        print('from index')
     
     
    print(index.__name__)
    print(index.__doc__)
     
    # 加@functools.wraps
    # index
    # 哈哈哈哈
     
    # 不加@functools.wraps
    # wrapper
    # None
    
    

    异常处理写法以及如何主动跑出异常(应用场景)

    # 触发异常
    def temp_convert(var):
        try:
            return int(var)
        except ValueError as Argument:
            print ("参数没有包含数字%s"%Argument)
    
    # 调用函数
    temp_convert("xyz")
    # 以10为基数的int()的无效文字:“xyz”
    
    ----------------------------------------------------------------------------
    # raise语法
    #raise [Exception [, args [, traceback]]]
    # 语句中 Exception 是异常的类型,args 是自已提供的异常参数。
    
    class Networkerror(RuntimeError):
        def __init__(self, arg):
            self.args = arg
    try:
        raise Networkerror("Bad hostname")
    except Networkerror as e:
        print(e.args)
    
    

    yield和yield from关键字

    yield 返回一个
    yield from 返回一堆
    
    1.yield from 将一个可迭代对象的每一个元素返回给next
    2.yield from 节省代码,提升效率(代替了for循环)
    
    
  • 相关阅读:
    运算符
    练习
    JAVA学习日报 9/23
    JAVA学习日报 8.22
    JAVA学习日报 8.21
    第一节:SpringMVC 处理请求数据【1】
    第六节:@RequestMapping 映射请求占位符 @PathVariable 注解
    第一节:REST 风格的URL地址约束
    第二节:REST风格的案例及源码分析
    (一)IOC 容器:【1】@Configuration&@Bean 给容器中注册组件
  • 原文地址:https://www.cnblogs.com/saoqiang/p/12453733.html
Copyright © 2020-2023  润新知