• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
zlik8991
博客园    首页    新随笔    联系   管理    订阅  订阅
python随笔day02

python面试基础问题

1.arg元组类型和**kwargs字典类型

#元组参数:元组类型数据,对传递参数有顺序要求
def test(*args):
    print(f"args[0]={args[0]},args[1]={args[1]},args[2]={args[2]}")

test(1,2,3)
#字典参数:字典类型数据,对传递参数没有顺序要求,格式要求key = value值
def test2(**kwargs):
    print(f"name={kwargs['name']},age={kwargs['age']},gender={kwargs['gender']}")

test2(name='Tom',age=20,gender='male')

#注意:无论是包裹位置传递还是包裹关键字传递,都是一个组包的过程。

2.对于一个函数num, 当调用 num(1,2,a=3,b=4)和调用 num(3,4,5,6,a=1)以及 num(a=1,b=2)的时候都可以正常运行,并且可以对元组以及字典类型进行遍历输出,对字典类型进行输出字典的键值对(形式为:key:a,value:1),写函数num?

def num(*args,**kwargs):
    for i in args:
        print(i)

    for k,v in kwargs.items():
        print(f"key:{k},value:{v}")

num(1,2,3,4,5,name='Tom',age=20,gender='male')
#结果如下:
# 1
# 2
# 3
# 4
# 5
# key:name,value:Tom
# key:age,value:20
# key:gender,value:male

3.当我们需要使用格式化输出一个 %号时,需要在后边写两个 %%

print("%d%%及格"%(50))#50%

4.字符串切片问题

[start:stop:step]

start:起始位置的索引(包含)。如果未指定,则默认为序列的起始位置。

stop:结束位置的索引(不包含)。如果未指定,则默认为序列的结束位置。

step:步长,用于指定取元素的间隔,默认为1。

a="abcdefg"
print(a[::])#start:end:step都是默认,从头到尾输出"abcdefg"
print(a[3::-2])#从第3个开始,步长为-2,输出"db"
print(a[6::-2])#从第6个开始,步长为-2,输出"geca"
print(a[1:6:2])#从第1个开始,步长为2,输出"bdf"
print(a[::-1])#步长为-1,反向输出,输出"gfedcba"
print(a[::2])#步长为2,输出"aceg"
print(a[1::2])#步长为2,从第1个开始,输出"bdf"

5.在字典中,如果key是数字类型,如果两个值相等,则后面这个key会替换前面这个key的value值。下面1和1.0值相等,value1.0直接替换value1,也就是3。

总结:

(1)字典的键在比较时考虑的是相等性(__eq__),而不是身份(is)。

(2)整数和浮点数在数值相等时,在字典的键比较中会被视为相等,但这并不意味着它们在字典内部存储时会合并为一个键。

(3)字符串和整数(或浮点数,如果它们表示相同的数值)在字典中总是被视为不同的键。

my_dict = {}
my_dict[1] = 1
my_dict['1'] = 2
print(my_dict)  #{1: 1, '1': 2}
my_dict[1.0] = 3
print(my_dict)  #{1: 3, '1': 2}
print(my_dict[1] + my_dict['1'] + my_dict[1.0])  # 8

6.深拷贝、浅拷贝、赋值三个区别?(这些复制会影响原始数据和副本数据之间的关系)

(1)深拷贝

深拷贝不仅创建了一个新的对象,而且递归地复制原始对象中包含的所有对象(无论嵌套多深),使得新对象和原始对象完全独立。对深拷贝对象所做的任何修改都不会影响到原始对象。

import copy  
  
a = [1, 2, [3, 4]]  
b = copy.deepcopy(a)  # 深拷贝  
b[2].append(5)  
print(a)  # 输出 [1, 2, [3, 4]],a和b完全独立

(2)浅拷贝

浅拷贝会创建一个新的对象,这个新对象有着原始对象属性值的精确拷贝。但是,如果原始对象的属性值本身也是对象(即嵌套对象),则浅拷贝不会递归地复制这些嵌套对象,而是复制它们的引用。因此,对于嵌套对象,原始对象和浅拷贝对象之间仍然存在共享关系。

import copy  
  
a = [1, 2, [3, 4]]  
b = copy.copy(a)  # 浅拷贝  
b[2].append(5)  
print(a)  # 输出 [1, 2, [3, 4, 5]],因为a和b共享第三个元素的引用

(3)赋值

赋值是最简单的数据传递方式。当你将一个对象赋值给另一个变量时,你实际上是在创建一个指向原始对象引用的新变量,而不是创建一个新的对象。因此,两个变量都指向内存中的同一个对象。对其中一个变量所做的任何修改都会反映到另一个变量上,因为它们共享同一个数据。

a = [1, 2, 3]
b = a
print("赋值")
print(id(a),a)  # 2852076541632 [1, 2, 3]
print(id(b),b)  # 2852076541632 [1, 2, 3]
b.append(4)
print(id(a),a)  # 2852076541632 [1, 2, 3, 4]
print(id(b),b) # 2852076541632 [1, 2, 3, 4]

7.数学方法趋近于值

通过蒙特卡罗方法估计一个特定的数学表达式。具体来说,它通过生成大量的随机点,并计算这些点满足特定条件的比例,来估计表达式 (math.pi - 2) / (4 - math.pi)的值。

#import random
def foo(n):
    random.seed()
    c1=0
    c2=0
    for i in range(n):
        x=random.random()
        y=random.random()
        r1=x*x+y*y
        r2=(1-x)*(1-x)+(1-y)*(1-y)
        if r1<=1 and r2<=1:
            c1+=1
        else:
            c2+=1
    return c1/c2

print(foo(10000000))#n无限大的时候结果趋近于(math.pi-2)/(4-math.pi)
  1. 简述python中的内置装饰器@classmethod,@staticmethod和@property作用及区别?

    (1)classmethod

    @classmethod装饰器用于将类中的方法转换为类方法,类方法接收类本身作为第一个参数(通常命名为 cls),而不是类的实例。这使得类方法可以在不创建类实例的情况下被调用,并能够访问类的属性(包括类变量和类方法)。建议直接使用,不用实例化对象。

    class MyClass:  
        count = 0  # 类变量  
    
        @classmethod  
        def get_count(cls):  
            """返回类的实例数量"""  
            return cls.count  
    
        @classmethod  
        def increment_count(cls):  
            """增加类的实例数量(注意:这里只是演示,实际用途可能不同)"""  
            cls.count += 1  
    
    # 使用类方法  
    print(MyClass.get_count())  # 输出: 0  
    MyClass.increment_count()  
    print(MyClass.get_count())  # 输出: 1
    

    (2)staticmethod
    @staticmethod装饰器用于将类中的方法转换为静态方法,在类的静态方法中无法调用任何类属性和类方法,因为静态方法没有类似 self、cls 这样的特殊参数,因此 Python 解释器不会对它包含的参数做任何类或对象的绑定。

    class MyClass:  
        @staticmethod  
        def helper_function(a, b):  
            """这是一个静态方法,用于演示静态方法的用法"""  
            return a + b  
    
    # 使用静态方法  
    result = MyClass.helper_function(1, 2)  
    print(result)  # 输出: 3
    

    (3)property

    用于将方法转换为只读属性,以提供更灵活的属性访问方式(包括setter和deleter用于写操作)。

    class Person:  
        def __init__(self, name):  
            self._name = name  # 使用下划线前缀表示私有属性  
      
        @property  
        def name(self):  
            """Getter方法,返回_name的值"""  
            return self._name  
      
        @name.setter  
        def name(self, value):  
            """Setter方法,设置_name的值"""  
            if not isinstance(value, str):  
                raise ValueError("Name must be a string")  
            self._name = value  
      
    # 使用Person类  
    p = Person("Alice")  
    print(p.name)  # 输出: Alice  
    p.name = "Bob"  # 使用setter方法设置新值  
    print(p.name)  # 输出: Bob  
      
    # 尝试设置非字符串类型的值,将引发异常  
    # p.name = 123  # 这将抛出ValueError
    
  2. setter的作用?

    setter并不是一个独立的内置装饰器,而是与 @property装饰器一起使用的一个特性。通过 @property装饰的方法只能被读取(像访问属性一样),但可以通过定义同名但带有 .setter后缀的方法来允许外部代码设置这个属性的值。

    class Animal:
        def __init__(self,color):
            self.color = color
        @property
        def color(self):
            return self.__color
    
        @color.setter
        def color(self,color):
            self.__color = color
    
    animal = Animal("red")
    print(animal.color)#red
    animal.color = "blue"
    print(animal.color)#blue 属性值被改变了
    

10.remove():remove()方法会根据元素本身的值进行删除。要注意的是:①该方法只会删除遇见的第一个指定元素,如果列表中还有相同的元素是不会被删除的;②必须保证要删除的元素在列表中是存在的,否则会报错。

list = [1, 1, 1, 2, 3, 4, 5]
list.remove(1)
print(list) #[1, 1, 2, 3, 4, 5]
list.extend([6, 7, 8])
print(list) #[1, 1, 2, 3, 4, 5, 6, 7, 8]

11.递归算法

① 简化问题:找到最优子问题(不能再小)

② 函数自己调用自己

#斐波拉契数列1,1,2,3,5,8,13,21,34,55,89,144...
def fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)
  
print(fib(10))#55

#递归求数的阶乘
def a(n):
    if n<2:
        return 1
    else:
        return n*a(n-1)
  
print(a(5))#120

12.猴子吃桃问题

猴子第1天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第2天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半另加一个。到第10天早上想再吃时,就只剩下一个桃子了。求第1天共摘了多少个桃子?

第十天 1个

第九天(1+1)*2=4个

第八天(4+1)*2=5个

............以此类推

def f(n):
    if n == 10:
        return 1
    return (f(n+1) + 1) * 2

# 调用函数
print(f"第一天摘了{f(1)}桃子")#1534
posted on 2024-07-06 21:31  zliky_55  阅读(26)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3