Python基础篇练习题

第一部分 必答题(每题2分)

  1. 简述列举了解的编程语言及语言间的区别?

    编译型:一次性全部编译成二进制码,再去运行
    解释型:编译一句,运行一句
    c语言:编译型语言,一种能以简易的方式编译、处理低级存储器、仅产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言,属于底层语言,只有面向过程,没有面向对象
    c++:编译型语言,是C语言的继承,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计
    go语言:编译型语言,应用在区链块,高并发高可用,游戏方向
    c#:混合性语言,是一种安全的、稳定的、简单的、优雅的,由C和C++衍生出来的面向对象的编程语言
    java:混合型语言,应用最广泛地语言,学习成本高,开发周期长
    python:解释型语言,简单易学类库多
    php:解释型语言,主要用于快速开发网站
    
  2. 列举Python2和Python3的区别?

    python2 print可以不带括号,默认编码ascii不支持中文,类有经典类和新式类之分,带上小数点/表示真除,print(range(0,4))的结果是列表,打开文件file( ..... ),raw_input输入
    Python3 print带括号,默认编码utf-8支持中文,只有新式类,range(0,4)是可迭代对象,打开文件open(......),input输入
    
  3. 看代码写结果

    优先级:not > and > not 
    and 同真取后,同假取前,一真一假取假;or 同假取后 同真取前 一真一假取真
    逻辑短路:True or 表达式(print(1)) ==> True  False and 表达式(print(1))==>False
    布尔值为假的情况:bool() => False  0,0.0,False,0j,'',[],(),set(),{},None
    complexvar = 3 + 4j
    3 : 实数
    4j: 虚数
    j: 如果有一个数,他的平方等于-1 ,那么这个数就是j,科学家认为有,表达高精度类型
    v1 = 1 or 2
    v2 = 3 and 7 or 9 and 0
    结果:v1 = 1  v2 = 7
    
  4. 比较以下值有什么不同?

    v1 = [1,2,3]
    v2 = [(1),(2),(3)]
    v3 = [(1,),(2,),(3,)]
    结果:v1和v1结果相同,v3是列表套元组,括号中元组有逗号,否则是什么数据类型就是什么数据类型
    v3 = [(1),(1.1),("a")]  ==> [(int),(float),(str)]
    
  5. 用一行代码实现数值交换。

    a = 1
    b = 2
    结果:a,b = b,a
    
  6. Python中单引号、双引号、三引号的区别?

    单引号、双引号、三引号都可以用于表达字符串,三引号还可以用于多文本输入,三引号还可以用于注释,在互相嵌套时需注意:里外不能使用相同的引号
    
  7. is和==的区别?

    is 是查看两端的数据的内存地址是否相同
    == 是查看两端的值是否相同
    
  8. python里如何实现tuple和list的转化?

    lst = [1,2,3]
    tu = (4,5,6)
    print(list(tu))  # [4, 5, 6]
    print(tuple(lst))  # (1, 2, 3)
    
  9. 如何实现字符串 name='老男孩'的反转?

    name = '老男孩'
    print(name[::-1])
    print("".join(sorted([i for i in name])))
    
  10. 两个set如何获取交集、并集、差集,反交集?

    s1 = {1,2,3,4,5}
    s2 = {1,2,6,7,8}
    print(s1&s2)
    print(s1|s2)
    print(s1-s2)
    print(s1^s2)
    
  11. 那些情况下, y != x - (x-y)会成立?

    # y不能是x的子集
    x = {1,2,3,4,5}
    y = {1,2,6,7,8}
    print(y)
    print(x-(x-y))
    print(y != x-(x-y))  # True
    
  12. Python中如何拷贝一个对象?

    import copy
    x = {1,2,3,4,5}
    y = {1,2,6,7,8}
    print(copy.copy(x))
    print(copy.deepcopy(y))
    # 针对于列表的拷贝,还可以使用[:] , [::],浅拷贝的一种方式
    
  13. 简述 赋值、浅拷贝、深拷贝的区别?

    赋值:多个变量名指向同一个内存地址,一个变量对其操作,其他变量查看时都变动
    浅拷贝:只拷贝第一层空间,即开辟新的内存地址,不可变数据和可变数据共用
    深拷贝:开辟一块新的内存空间,不可变数据共用,可变数据重新开辟空间
    
  14. pass的作用?

    pass 占位,为了保持程序结构的完整性
    
  15. 阅读代码写结果。

    import copy
    a = [1,2,4,5,['b','c']]
    b = a
    c = copy.copy(a)
    d = copy.deepcopy(a)
    
    a.append(5)
    a[4].append('d')
    
    print(b)  # [1,2,4,5,['b','c','d'],5]
    print(c)  # [1,2,4,5,['b','c','d']]
    print(a)  # [1,2,4,5,['b','c','d'],5]
    print(d)  # [1,2,4,5,['b','c']]
    
  16. 用Python实现9 * 9 乘法表。

    方法一:
    for i in range(9,0,-1):
        for t in range(1, i + 1):
            print("%d*%d=%2d" % (i,t,i*t), end=" ")
        print()  # 打印换行
    方法二:
    for i in range(1,10):
        for t in range(1, i + 1):
            print("%d*%d=%2d" % (i,t,i*t), end=" ")
        print()  # 打印换行
    方法三:
    i = 1
    while i <= 9:
        t = 1
        while t <= i:
            print("%d*%d=%2d" % (i,t,i*t), end=" ")
            t += 1
        print()
        i += 1
    
  17. 用Python显示一个斐波那契数列。

    方法一:
    lst = [1,1]
    num = int(input("请输入一个数字:"))
    def func(f):
        if lst[-1] + lst[-2] <= num:
            lst.append(lst[-1] + lst[-2])
            return func(lst)
        else:
            return lst
    print(func(lst))
    方法二:
    a,b = 0,1
    num = int(input("请输入一个数字:"))
    for i in range(num):
        print(b)
        a,b = b,a+b
    print(b)
    方法三:
    lst = [1,1]
    num = int(input("请输入一个数字:"))
    for i in range(num):
    	lst.append(lst[-1] + lst[-2])
    print(lst)
    
  18. 如何删除列表中重复的值?

    lst = [1,1,2,2,3,4]
    print(list(set(lst)))
    
  19. 一个大小为100G的文件etl_log.txt, 要读取文件中的内容, 写出具体过程代码?

    with open('1.txt',mode="r",encoding="utf-8") as f:
        print(f.read())
    
  20. a = dict(zip(("a","b","c","d","e"),(1,2,3,4,5))) 请问a是什么?

    {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
    # zip  拉链
    a = dict(zip(("a","b"),[1,2,3]))
    print(a)
    # enumerate  枚举
    a = dict(enumerate(["a","b"]))
    a = dict(enumerate(["a","b"],start = 10))
    print(a)
    
  21. lambda关键字的作用?

    lambda 匿名函数 : 用一句话表达只有返回值的无名函数
    lambda 参数 : 返回值
    
  22. *arg**kwarg作用?

    *args 动态位置参数,可以接受0个或多个位置参数,返回元组,不传值时()
    *kwargs 动态关键字参数,可以接受0个或多个关键字参数,返回字典,不传值时{}
    
  23. 如何在函数中设置一个全局变量 ?

    global:在函数内部修改全局空间的变量对应的值;声明一个全局变量
    
  24. filter、map、reduce的作用?

    filter用于筛选过滤
    lst = [i for i in range(10)]
    s = filter(lambda x:True if x % 2 == 0 else False,lst)
    print(list(s))  # [0, 2, 4, 6, 8]
    map是映射函数
    lst = [1,2,3]
    it = map(lambda x : x*3 , lst)
    print(list(it))
    reduce用于函数计算
    from functools import reduce
    lst = [5,4,8,8]
    res = reduce(lambda x,y: x*10 + y,lst)
    print(res, type(res))
    
  25. Python递归的最大层数?

    官方说法1000 , 实际测试 994 ~ 1000
    import sys
    sys.setrecursionlimit(1000) # 修改递归的最大深度
    
  26. 什么是迭代器?什么是可迭代对象?

    内部含有__iter__方法并且含有__next__方法的对象就是迭代器
    凡是内部含有__iter__方法的对象,都是可迭代对象
    # 迭代器一定是可迭代对象,可迭代对象不一定是迭代器
    
  27. 什么是生成器?

    生成器的本质就是迭代器,迭代器是python自带的工具,生成器是程序员自己写的
    创建方式两种:
    	(1)生成器表达式 (推导式)  (i for i in range(3))
    	(2)生成器函数   (含有yield关键字)
    
  28. 什么是装饰器及应用场景?

    装饰器:装饰器的本质是闭包,在不改变原被装饰的函数的原代码以及调用方式下,为其添加额外的功能。
    登录认证,django框架等
    
  29. 什么是反射及应用场景?

    通过字符串去操作类对象或者模块中的属性、方法
    hasattr,getattr,setattr,delattr
    应用: 可以配合用户的操作或者输入,调用其中的成员,api接口中
    
  30. 写一个普通的装饰器。

    def wrapper(f):
        def inner(*args,**kwargs):
            # 此处执行被装饰函数之前的操作
            ret=f(*args,**kwargs)
            # 此处执行被装饰函数之后的操作
            return ret
        return inner
    @wrapper
    def func():
        pass
    func()
    
  31. 写一个带参数的装饰器。

    def wrapper(n):
        def inner(func):
            def timer1(*args,**kwargs):
                ret = func(*args,**kwargs)
                print(1)
            def timer2(*args,**kwargs):
                ret = func(*args,**kwargs)
                print(2)
            if n == "alex":
                return timer1
            else:
                return timer2
        return inner
    @wrapper("alex")
    def home():
        pass
    home()
    
  32. 求结果

    def num():
      return [lambda x:i*x for i in range(4)]
    print([m(2) for m in num()])
    # 解析
    def出现的位置是函数的定义处
    函数() 出现的位置是函数的调用处
    (1)调用的时候,才会把函数中的代码,从上到下执行一遍,否则不执行
    (2)里面的func是一个闭包函数,延长了当前变量i的生命周期,最后一次i的值3,所以再去调用时候拿的3
    def num():
        # [lambda x:i*x for i in range(4)]
        lst = []
        for i in range(4):
            def func(x):
                return i*x
            lst.append(func)
        return lst
    print(num())
    # 函数是从左向右依次执行,先调用num()函数,此时for循环已经执行完成了
    # m其实是列表中函数对象地址,m=func,再调用func函数,此时i=3
    #[6,6,6,6]
    
  33. def(a, b=[])这种写法有什么陷阱?

    b身上的默认值是列表,如果使用原来默认的参数,调用func函数,会把几次调用的值都存放在同一个默认列表里
    
  34. 看代码写结果

    def func(a,b=[]):
        b.append(a)
    	return b
    
    v1 = func(1)
    v2 = func(2,[10,20])
    v3 = func(3)
    print(v1,v2,v3) # [1, 3] [10, 20, 2] [1, 3]
    
  35. 看代码写结果

    def func(a,b=[]):
        b.append(a)
    	return b
    
    v1 = func(1)
    print(v1)  # [1]
    v2 = func(2,[10,20])
    print(v2)  # [10, 20, 2]
    v3 = func(3)
    print(v3)  # [1, 3]
    
  36. 请编写一个函数实现将IP地址转换成一个整数。

    如 10.3.9.12 转换规则为:
            10            00001010
             3            00000011
             9            00001001
            12            00001100
            
    再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?
    
    ip = "10.3.9.12"
    print(int("".join(format(int(i),"08b") for i in ip.split(".")),2))
    方法一:
    s = ""
    for i in ip.split("."):
        s += format(int(i),"08b")
    print(int(s,2))
    方法二:
    s = ""
    for i in ip.split("."):
        # 0b.....
        bin_str = str(bin(int(i)))[2:]
        # 总长度是8 原字符串居右
        # ljust   原字符串居左,填充符号
        # rjust   原字符串居右,填充符号
        s += bin_str.rjust(8,"0")
    # 把二进制字符串转换成十进制,默认转换时,是十进制
    print(int(s,2))
    
  37. 请查找一个目录下的所有文件(可能存在文件嵌套)。

    方法一:
    import os
    def getallsize(pathvar):
        size = 0
        # 将文件名添加到列表
        lst = os.listdir(pathvar)
        for i in lst:
            # 拼接为绝对路径
            pathvar2 = os.path.join(pathvar,i)
            # 判断是文件夹还是文件
            if os.path.isfile(pathvar2):
                size += os.path.getsize(pathvar2)
            elif os.path.isdir(pathvar2):
                # 文件夹递归读取
                size += getallsize(pathvar2)
            print(size)
        return size
    
    pathvar = r"E:预习视频python25期视频s25串讲"
    res = getallsize(pathvar)
    print(res)
    方法二:
    import os
    # os.walk() => 生成器
    def getallsize1(pathvar):
        size = 0
        gen = os.walk(pathvar)   # 形成一个生成器
        for root,dirs,files in gen:  # 根据内容分别赋值
            for name in files:
                pathvar = os.path.join(root,name)  # 得到所有的文件路径
                size += os.path.getsize(pathvar)
        return size
    pathvar = r"E:预习视频python25期视频s25串讲"
    res = getallsize1(pathvar)
    print(res)
    
  38. 求结果

    import math
    
    print(math.floor(4.8))  # floor向下取整  4
    print(math.ceil(4.2))   # ceil向上取整   5
    print(round(4.5))       # 4为偶,不进    4
    print(round(4.51))      # 奇进偶不进只适用于x.5
    print(round(5.5))       # 5为偶,进位    6
    
  39. 是否使用过functools中的函数?其作用是什么?

    from functools import reduce
    lst = [5,4,8,8]
    res = reduce(lambda x,y: x*10 + y,lst)
    print(res, type(res))  #  5488 <class 'int'>
    
    from functools import wraps
    def wrapper(func):
        @wraps(func)  # 保留原函数的属性
        def inner(*args,**kwargs):
            res = func(*args,**kwargs)
            print(1)
            return res
        return inner
    
    @wrapper
    def home():
        print(2)
    
    home()
    print(home)
    
  40. re的match和search区别?

    match : 必须从字符串的开头进行匹配
    search: 从任意位置开始匹配,匹配到就返回,只匹配一个
    
  41. 用Python匹配HTML tag的时候,<.>和<.?>有什么区别?

    . 除了
    的任意字符
    * 量词,代表匹配0次或者多次,任意个
    .*  贪婪匹配
    .*? 非贪婪匹配
    
  42. 如何生成一个随机数?

    import random
    random.random    随机获取 0<= x < 1
    random.randrange 随机获取指定范围中的整数,用法上同range
    random.uniform   随机获取指定范围中的小数
    
  43. super的作用?

    跳过本类
    单继承时,按照深度优先原则,查找下一类
    多继承时,严格按照对象从属于类的mro顺序查找下一类
    
  44. 双下划线和单下划线的区别?

    class MyClass():
    	__abc = 90
    	_ppp = 100
    """
    封装: 公有public 私有private 受保护的protected
    私有: 只能在当前这个类里面使用,不能在子类或者在类外使用
    受保护的: 可以在当前这个类或者子类里使用,不能在类外使用
    约定俗成在该变量前面加上一个下划线_ , 就表示受保护了
    """
    
  45. @staticmethod和@classmethod的区别?

    一个静态方法,一个类方法
    一个静态方法:(无论是对象还是类,都可以调用,不会默认传递任何参数)
    一个类方法  :(无论是对象还是类,都可以调用,会默认传递类这个参数)
    
  46. 实现一个单例模式(加锁)。

    # 单态模式:这个类无论实例化多少次,都有且只有一个对象
    from threading import Lock
    class MyClass(object):
    	__obj = None
    	lock = Lock()
    	def __new__(cls,*args,**kwargs):
    		with cls.lock:
    			if not cls.__obj:
    				cls.__obj = object.__new__(cls)
    			return cls.__obj
    obj1 = MyClass()
    obj2 = MyClass()
    print(obj1,obj2)
    
  47. 栈和队列的区别?

    栈 :  先进后出,或者 后进先出
    队列: 先进先出
    
  48. 以下代码输出是什么? 请给出答案并解释。

    class Parent(object):
    	x = 1
    class Child1(Parent):
    	pass
    class Child2(Parent):
    	pass
    # 1 1 1
    print(Parent.x, Child1.x, Child2.x)
    Child1.x = 2
    # 1 2 1
    print(Parent.x, Child1.x, Child2.x)
    Parent.x = 3
    # 3 2 3
    print(Parent.x, Child1.x, Child2.x)
    
  49. 参考下面代码片段

    class Content:
        pass
    
    with Content() as ctx:
        ctx.do_something()
    请在Context类下添加代码完成该类的实现
    class Content():
        def __enter__(self):
            # 返回的结果就是ctx,任意内容
            return self
        def __exit__(self, exc_type, exc_val, exc_tb):
            print(123)
        def do_something(self):
            print(456)
    # 面向对象的上下文管理是with语法的具体实现,自动执行__enter__和__exit__方法
    with Content() as ctx:
        ctx.do_something()
        print(666)
    

第二部分 可选题

  1. 如何获取列表中第二大的值?

    所有的容器类型数据都可以通过 sorted (sort只局限于列表进行排序)
    # 去重
    lst = [1,2,4,3,6,3,8,8,7]
    lst = set(lst)
    res = sorted(lst)
    res_new = res[-2]
    print(res_new)
    
  2. 简述Python内存管理机制

    内存管理机制是由计数器,垃圾回收,内存池组成
    1.计数器
    特点:引用技术如果是0,把这个值从内存中释放掉
    a = 100
    b = a
    print(b)
    del b
    缺点:在维护引用计数时,有可能数据产生循环引用,造成数据不能删除,造成内存泄漏,为了解决此情况,引入标记清除
    lst1 = [1,2]
    lst2 = [5,6]
    lst1.append(lst2)
    lst2.append(lst1)
    del lst1
    print(lst1)
    print(lst2)
    
    2.垃圾回收:引用计数为主,标记清除和分代回收为辅
    标记清除 : 检测标记该对象,避免出现循环引用不能删除的现象
    分代回收 :
    	把内存中的数据分成三个区域: 新生代0,老年代1,永久代2
    	新生代0数据超过700 , 或者老年代1,永久代2数据超过10,自动触发内存中的垃圾回收机制
    	新生代0触发将清除所有三代的区域
    	老年代1触发会清理1,2代
    	永久代2触发只会清理自己
    3.内存池
    	在同一个文件当中 (python3.6)
        -->Number 部分
    	1.对于整型而言,-5~正无穷范围内的相同值 id一致
    	2.对于浮点数而言,非负数范围内的相同值 id一致
    	3.布尔值而言,值相同情况下,id一致
    	4.复数在 实数+虚数 这样的结构中永不相同(只有虚数的情况例外)
         -->容器类型部分
    	5.字符串 和 空元组 相同的情况下,地址相同
    	6.列表,元组,字典,集合无论什么情况 id标识都不同 [空元组例外]
        在不同的文件当中
    	小数据池 ; 比如整型默认开辟 -5~256 这么多数据提前在内存中驻留
    
  3. 简述Python的垃圾回收机制。

    如上所述
    
  4. 请用两个队列来实现一个栈

    """
    栈   : 先进后出,后进先出
    队列 : 先进先出,后进后出
    """
    from queue import Queue
    
    class Stack():
        def __init__(self):
            # 封装两个自定义队列
            self.master_queue = Queue()
            self.minor_queue = Queue()
    
        def push(self,val):
            # 入栈
            self.master_queue.put(val)
    
        def pop(self):
            # 出栈
            # 如果队列中没有任何值,直接返回None
            if self.master_queue.qsize() == 0:
                return None
    
            while True:
                # 当队列总长度为1的时候,循环终止,把最后一个元素拿出来,为了满足栈后进先出的特点
                if self.master_queue.qsize() == 1:
                    value = self.master_queue.get()
                    break
    
                # 剩下还没有拿出来的元素,暂时放在2号队列中存储
                self.minor_queue.put(self.master_queue.get())
                """
                    minor_queue(1)
                    master_queue(2 3 4)
                    
                    minor_queue(2)
                    master_queue(3 4)
        
                    minor_queue(3)
                    master_queue(4)
                    """
            # 交换队列,重新循环,继续去最后一个值,如法炮制,a,b=b,a
            self.master_queue,self.minor_queue = self.minor_queue,self.master_queue
            return value
    
    obj = Stack()
    obj.push("a")
    obj.push("b")
    obj.push("c")
    
    print(obj.pop())  # c
    print(obj.pop())  # b
    print(obj.pop())  # a
    print(obj.pop())  # None
    
  5. Python实现一个链表

    class Node():
        def __init__(self, value, next):
            # 链表有两部分,前为值,后为下一个值的地址
            self.value = value
            self.next = next
    
    head = Node("头", None)
    last = head
    
    for i in range(5):  # v0 v1 v2 v3 v4
        node = Node("v%s" % i, None)
        last.next = node
        last = node
    
    # 查看链表的关系
    print(head.value)
    print(head.next.value)
    print(head.next.next.value)
    print(head.next.next.next.value)
    print(head.next.next.next.next.value)
    print(head.next.next.next.next.next.value)
    
  6. 实现链表的逆转

    class Node():
        def __init__(self, value, next):
            # 链表有两部分,前为值,后为下一个值的地址
            self.value = value
            self.next = next
    
    head = Node("头", None)
    last = head
    
    for i in range(5):  # v0 v1 v2 v3 v4
        node = Node("v%s" % i, None)
        last.next = node
        last = node
        
    def reverse_link_list(head):
        # 要是空的,或者None,直接返回head
        if not head or not head.next:
            return head
    
        # 获取上一个节点对象
        prev_node = None
        # 获取下一个节点对象
        next_node = head.next
        # 获取当前节点对象
        current_node = head
    
        while True:
            # 修改next,所指向的对象
            current_node.next = prev_node
            # 如果下一个阶段对象是None
            if not next_node:  # not None
                break
    
            # 重新获取上一个对象,即把当前丢向单独存一份,以准备第二次循环时插进next属性中
            prev_node = current_node
            # 重新获取当前对象 , 即把下一个对象单独存储起来(下个)
            current_node = next_node
            # 重新获取下一个对象,即把下一个对象单独存储起来,所指向的下个新对象赋值给next_node(下下个)
            next_node = current_node.next
        return current_node
    
    head = reverse_link_list(head)
    
    print(head.value)
    print(head.next.value)
    print(head.next.next.value)
    print(head.next.next.next.value)
    print(head.next.next.next.next.value)
    print(head.next.next.next.next.next.value)
    

技术顾问:王闻 xboyww 微信 123463922 qq号

原文地址:https://www.cnblogs.com/lvweihe/p/12366168.html