1 数据结构
可变类型:
- 列表(list)
- 字典(dict)
- 集合(set)
可以在原地修改值
不可变类型:
- 数字(int、float、complex)
- 布尔值(bool)
- 字符串(str)
- 元组(tuple)
- 不可变集合(frozenset)
不能原地修改,只能重新赋值
1.1 字符串
常见内置函数:
查找
- string.find(str, beg=0, end=len(string)):检测 str 是否包含在 string 中,如果 beg 和 end 指定范围,则检查是否包含在指定范围内,如果是返回开始的索引值,否则返回-1
- string.index(str, beg=0, end=len(string)):跟find()方法一样,只不过如果str不在 string中会报一个异常.
- string.count(str, beg=0, end=len(string)):返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数
替换
- string.replace(str1, str2, num=string.count(str1)):把 string 中的 str1 替换成 str2,如果 num 指定,则替换不超过 num 次.
分割
- string.split(str=“”, num=string.count(str)):以 str 为分隔符切片 string,如果 num 有指定值,则仅分隔 num+1 个子字符串
连接
- string.join(seq):以 string 作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串
排序
- list.sort(cmp=None, key=None, reverse=False):对原列表进行排序
反转
- list.reverse():反向列表中元素
https://www.runoob.com/python/python-strings.html
字符串的反转
可以利用切片进行反转:
s = "hello world"
s_reversed = s[::-1] # 切片反转字符串
print(s_reversed) # 输出:dlrow olleh
也可以使用 reversed()
函数反转字符串,代码示例如下:
s = "hello world"
s_reversed = ''.join(reversed(s)) # 使用 reversed() 函数反转字符串
print(s_reversed) # 输出:dlrow olleh
1.2 列表
常见内置函数
添加
- list.append(obj):在列表末尾添加新的对象
- list.extend(seq):在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
删除
- list.pop([index=-1]):移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
- list.remove(obj):移除列表中某个值的第一个匹配项
排序
- list.sort(cmp=None, key=None, reverse=False):对原列表进行排序
反转
- list.reverse():反向列表中元素
插入元素
- list.insert(index, obj):将对象插入列表
https://www.runoob.com/python/python-lists.html
1.3 元组
https://www.runoob.com/python/python-tuples.html
1.4 字典
删除元素
#!/usr/bin/python
# -*- coding: UTF-8 -*-
tinydict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
del tinydict['Name'] # 删除键是'Name'的条目
tinydict.clear() # 清空字典所有条目
del tinydict # 删除字典
- dict.clear():删除字典内所有元素
- pop(key[,default]):删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
- popitem():返回并删除字典中的最后一对键和值。
遍历
- dict.items():以列表返回可遍历的(键, 值) 元组数组
- dict.keys():以列表返回一个字典所有的键
- dict.values():以列表返回字典中的所有值
查询
- dict.get(key, default=None):返回指定键的值,如果值不在字典中返回default值
https://www.runoob.com/python/python-dictionary.html
2 内置方法
2.1 is
和==
的区别
is
用于判断两个变量引用对象是否为同一个, ==
用于判断引用变量的值是否相等。a is b
相当于 id(a)==id(b)
,id()
能够获取对象的内存地址。如果 a=10;b=a;
则此时 a
和 b
的内存地址一样的; 但当 a=[1,2,3];
另 b=a[:]
时,虽然 a 和 b 的值一样,但内存地址不一样。如果此时定义 a=10、b=10, 然后再对比 a is b 会发现返回的结果是 True,这是因为在 Python 中会实现创建一个小型的整形池,范围为 [-5,256],为这些整形开辟好内存空间,当代码中定义该范围内的整形时,不会再重新分配内存地址。
2.2 in和exist区别
2.3 with的用法
在 Python 中,with 语句提供了一种方便的方式来管理代码块中的资源,比如文件、网络连接和数据库连接等。它可以自动地为资源分配和释放资源,避免了手动管理资源的麻烦,并且可以保证资源在使用后被正确地关闭或释放。
with 语句的一般语法如下:
with expression [as variable]:
with-block
其中,expression 是一个返回上下文管理器对象的表达式,with-block 是一个语句块,variable 是一个可选的变量名,用于存储上下文管理器返回的值。
当执行 with
语句时,Python 会调用上下文管理器对象的 __ enter __
方法进入上下文管理器,并在 with-block 中执行代码。当代码块执行完毕时,Python 会调用上下文管理器对象的 __ exit __
方法退出上下文管理器,并释放资源。
下面是一些 with 语句的示例用法:
with open('file.txt') as f:
contents = f.read()
这个例子中,open
函数返回一个上下文管理器对象,当 with
语句开始执行时,Python 会调用 open
函数返回的对象的 __ enter __
方法打开文件。在 with
代码块中,我们可以读取文件内容并存储在 contents
变量中。当代码块执行完毕时,Python 会自动调用上下文管理器对象的 __ exit__
方法关闭文件。2. 向数据库插入数据:
with connect('localhost', 'user', 'password', 'database') as conn:
cursor = conn.cursor()
cursor.execute('INSERT INTO users (name, email) VALUES (%s, %s)', ('John', 'john@example.com'))
conn.commit()
这个例子中,connect 函数返回一个上下文管理器对象,当 with 语句开始执行时,Python 会调用 connect 函数返回的对象的 __ enter__ 方法建立与数据库的连接。在 with 代码块中,我们可以执行 SQL 命令并提交事务。当代码块执行完毕时,Python 会自动调用上下文管理器对象的 __ exit__ 方法关闭数据库连接。
在 with 语句中,as 子句是可选的,如果省略了 as 子句,则上下文管理器返回的值将被忽略。如果指定了 as 子句,则上下文管理器返回的值将存储在指定的变量中,可以在 with 代码块中使用。
总之,with 语句提供了一种方便的方式来管理资源,避免了手动管理资源的麻烦,并且可以保证资源在使用后被正确地关闭或释放。
3 函数
3.1 python函数参数类型
Python 函数中的参数类型包括:位置参数、默认参数、可变参数和关键字参数。位置参数通过参数位置传递,必须按照函数定义的顺序传递;默认参数在函数定义时指定默认值,可以不传递;可变参数使用 *args
表示,接受任意数量的位置参数,传递时使用 *
将参数序列展开;关键字参数使用 **kwargs
表示,接受任意数量的关键字参数,传递时使用 **
将参数字典展开。
3.2 *arg 和 **kwarg 作用
在python中,当*
和**
符号出现在函数定义的参数中时,表示任意数目参数收集。*arg
表示任意多个无名参数,类型为tuple
; **kwargs
表示关键字参数,为dict
,使用时需将*arg
放在**kwargs
之前,否则会有“SyntaxError: non-keyword arg after keyword arg”的语法错误
例子:
# *允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。
def f(a,*args):
print(args)
f(1,2,3,4)
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
print(sum)
calc(1,2,3,4)
# **,关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
def d(**kargs):
print(kargs)
d(a=1,b=2)
#在函数混合使用*以及**。
def h(a,*args,**kargs):
print(a,args,kargs)
h(1,2,3,x=4,y=5)
def person(name,age,**kw):
print('name:',name,'age:',age,'other:',kw)
person('Adam', 45, gender='M', job='Engineer')
当*
和**
语法出现在函数调用中时,它会解包参数的集合。例如,我们在调用函数时能够使用*
语法,在这种情况下,它与函数定义的意思相反,他会解包参数的集合,而不是创建参数的集合。
#通过一个元组给一个函数传递四个参数,并且让python将它们解包成不同的参数。
def func(a,b,c,d):
print(a,b,c,d)
a = (1,2,3,4)func(*a)
# 如果已经有一个元祖,在参数前加*,函数会把元祖中的元素一个一个传到函数里面
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
print(sum)
num = (1,2,3,4)
calc(*num)
#如果已经有一个dict,在参数前面加**,函数会把dict中所有键值对转换为关键字参数传进去
def person(name,age,**kw):
print('name:',name,'age:',age,'other:',kw)
extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra)
4 随机数
python可以使用random模块生成随机数,常用的方法有如下几种:
random.random():生成一个 0 到 1 之间的随机小数。
import random
x = random.random()
print(x) # 输出:0.123456789
random.randint(a, b):生成一个在指定范围内的随机整数,包括 a 和 b。
import random
x = random.randint(1, 100)
print(x) # 输出:42
random.choice(seq):从序列中随机选择一个元素。
import random
seq = ['apple', 'banana', 'orange']
x = random.choice(seq)
print(x) # 输出:banana
random.choice(seq):从序列中随机选择一个元素。
import random
seq = ['apple', 'banana', 'orange']
x = random.choice(seq)
print(x) # 输出:banana
random.shuffle(seq):将序列中的元素随机排序。
import random
seq = ['apple', 'banana', 'orange']
random.shuffle(seq)
print(seq) # 输出:['orange', 'apple', 'banana']
5 python中的深拷贝和浅拷贝的区别
在 Python 中,深拷贝和浅拷贝都是用于复制对象的方式,但它们复制对象的方式不同,它们的区别如下:
浅拷贝
浅拷贝是一种浅层次的复制方式,它只复制对象的最外层,而不会复制对象中的子对象。当我们对子对象进行修改时,原对象和拷贝对象都会受到影响。在 Python 中,可以使用 copy 模块中的 copy 方法来实现浅拷贝。
import copy
a = [1, 2, [3, 4]]
b = copy.copy(a)
a[2][0] = 5
print(a) # [1, 2, [5, 4]]
print(b) # [1, 2, [5, 4]]
深拷贝
深拷贝是一种深层次的复制方式,它不仅复制对象的最外层,还会递归复制对象中的子对象,直到所有子对象都被复制。当我们对子对象进行修改时,原对象不会受到影响,只有拷贝对象受到影响。在 Python 中,可以使用 copy 模块中的 deepcopy 方法来实现深拷贝。下面是一个深拷贝的例子:
import copy
a = [1, 2, [3, 4]]
b = copy.deepcopy(a)
a[2][0] = 5
print(a) # [1, 2, [5, 4]]
print(b) # [1, 2, [3, 4]]
在上述代码中,我们使用 deepcopy 方法对列表 a 进行了深拷贝,得到了一个新的列表 b。当我们修改 a 中的子列表 [3, 4] 中的第一个元素时,b 中的子列表不会受到影响。
需要注意的是,在实际开发中,选择深拷贝还是浅拷贝应该根据具体情况进行权衡。如果对象中不包含可变对象,或者我们只需要对最外层进行修改,那么使用浅拷贝即可。如果对象中包含可变对象,或者需要对对象中的子对象进行修改,那么使用深拷贝可以避免出现意外的影响。
6 python中的面向对象
在 Python 中,我们可以使用类(class)来定义一个对象,类可以包含属性(attribute)和方法(method),属性表示对象的数据,方法表示对象的行为。通过使用类,我们可以创建多个相似的对象,并对其进行操作和管理。
下面是一个简单的面向对象编程示例,用于定义一个矩形对象:
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
在上述代码中,我们定义了一个名为 Rectangle 的类,包含了两个属性 width 和 height,以及两个方法 area 和 perimeter,分别用于计算矩形的面积和周长。通过使用这个类,我们可以创建多个矩形对象,并对其进行操作和管理。
下面是一个使用这个类的示例,用于创建一个矩形对象,并计算它的面积和周长:
rect = Rectangle(10, 5)
print(f'Width: {rect.width}, Height: {rect.height}')
print(f'Area: {rect.area()}')
print(f'Perimeter: {rect.perimeter()}')
7 python中的模块
在 Python 中,模块(module)是一个包含 Python 定义和语句的文件。模块可以包含变量、函数、类等代码,可以被其他 Python 程序引入和使用。通过使用模块,我们可以将代码组织成更加清晰和可维护的结构,并提高代码的复用性和可扩展性。
Python 中的模块可以使用 import 语句引入,引入后可以使用模块中定义的变量、函数、类等代码。下面是一个简单的模块示例,用于定义一个计算器模块:
# calculator.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
raise ValueError('Cannot divide by zero')
return a / b
在上述代码中,我们定义了一个名为 calculator 的模块,包含了四个函数 add、subtract、multiply 和 divide,分别用于执行加减乘除操作。这个模块可以被其他 Python 程序引入和使用。
下面是一个使用这个模块的示例,用于计算两个数的和、差、积和商:
import calculator
a = 10
b = 5
print(f'{a} + {b} = {calculator.add(a, b)}')
print(f'{a} - {b} = {calculator.subtract(a, b)}')
print(f'{a} * {b} = {calculator.multiply(a, b)}')
print(f'{a} / {b} = {calculator.divide(a, b)}')
在上述代码中,我们使用 import 语句引入了 calculator 模块,并使用模块中定义的四个函数执行计算操作。通过使用模块,我们可以将计算器功能封装起来,使得代码更加清晰和易于维护。
需要注意的是,在实际开发中,模块的设计和使用应该根据具体情况进行考虑。合理的模块设计可以帮助我们提高代码的组织性和可维护性,从而提升开发效率和代码质量。
8 python的异常处理
在 Python 中,异常处理是一种机制,用于捕获和处理程序中出现的异常情况。当程序运行过程中发生异常时,异常处理机制会捕获异常,并进行相应的处理,从而避免程序崩溃或出现不可预料的行为。
异常处理通常使用 try
和 except
语句来实现。try
语句用于执行可能会出现异常的代码块,except
语句用于捕获和处理异常。如果 try
语句中的代码块正常执行,程序会跳过 except
语句并继续执行后面的代码。如果 try
语句中的代码块发生异常,程序会跳转到最近的 except
语句,并执行相应的异常处理代码。
下面是一个简单的异常处理例子,用于读取文件中的整数并计算它们的和:
try:
with open('numbers.txt', 'r') as f:
nums = [int(line.strip()) for line in f]
total = sum(nums)
print(f'Total: {total}')
except FileNotFoundError:
print('File not found')
except ValueError:
print('Invalid number format')
except Exception as e:
print(f'Error: {e}')
在上述代码中,我们使用 try
语句来读取文件 numbers.txt
中的整数,并计算它们的和。如果文件不存在或文件中包含无效的数字,程序会抛出相应的异常,并执行相应的异常处理代码。其中,FileNotFoundError 是 Python 内置的异常类型,用于处理文件不存在的情况;ValueError 是内置的异常类型,用于处理无效的数据格式;Exception 是所有异常类型的基类,用于处理其他未知的异常情况。
需要注意的是,在实际开发中,异常处理应该根据具体情况进行设计和实现。合理的异常处理可以帮助我们提高程序的健壮性和可维护性,从而提升开发效率和用户体验。
9 python多线程和多进程
在 Python 中,多线程和多进程都是实现并发编程的方式,它们可以同时执行多个任务,提高程序的处理效率。它们的区别和适用场景如下:
- 多线程:多线程是一种并发编程的方式,它可以在同一个进程中创建多个线程,每个线程都可以独立执行任务。多线程可以共享进程的内存空间,从而可以方便地共享数据和资源。多线程适用于 I/O 密集型任务,例如网络通信、文件读写等,以及需要共享数据和资源的任务。
- 多进程:多进程是一种并发编程的方式,它可以在操作系统中创建多个进程,每个进程都可以独立执行任务。多进程可以通过进程间通信来共享数据和资源,但是相比于多线程,进程间的通信成本更高。多进程适用于 CPU 密集型任务,例如计算密集型算法、图像处理等,以及需要隔离和保护数据和资源的任务。
10 __new__ 和 __init__ 的区别
__new__
方法和__init__
方法都是python中的构造方法,其中__new__
方法使用较少,__init__
方法使用较多。
10.1 首先了解一下这两种方法
-
__new__
是在实例创建之前被调用的,用于创建实例,然后返回该实例对象,是个静态方法。 -
__init__
是当实例对象创建完成后被调用的,用于初始化一个类实例,是个实例方法。
由上可知,__new__先被调用,__new__的返回值将传递给__init__方法的第一个参数,然后__init__被调用,给这个实例设置一些参数。
实例:
class A():
def __new__(cls, *args, **kwargs):
print('this is A __new__')
# return super(A, cls).__new__(cls) # 或者下面这种形式,两种都可
return object.__new__(cls)
def __init__(self, title):
print('this is A __init__')
self.title = title
a = A('python book')
输出结果:
this is A __new__
this is A __init__
10.2 两种方法的区别
-
__new__
至少要有一个参数cls,且必须要有返回值,返回的是实例化出来的实例,有两种return方式:
return super(父类,cls).__new__(cls)
或者
return object.__new__(cls)
-
__init__
有一个参数self
,就是这个__new__
返回的实例,__init__
在__new__
基础上完成一些其他初始化的动作,__init__
不需要有返回值;
注意事项
- 如果
__new__
没有返回cls(即当前类)的实例,那么当前类的__init__
方法是不会被调用的
实例:
class A():
def __new__(cls, *args, **kwargs):
print('this is A __new__')
# return super(A, cls).__new__(cls)
def __init__(self, title):
print('this is A __init__')
self.title = title
a = A('python book')
输出结果:
this is A __new__
- 在定义子类的时候,没有重新定义__new__方法,那么直接继承父类的__new__方法构造该类的实例;
class A():
def __new__(cls, *args, **kwargs):
print('this is A __new__')
return super(A, cls).__new__(cls)
def __init__(self, title):
print('this is A __init__')
self.title = title
class B(A):
def __init__(self, title):
print('this is B __init__')
self.title = title
b = B('python book')
输出结果
this is A __new__
this is B __init__
- 在定义子类的时候,重写__new__方法,就不会调用父类的__new__方法;
class A():
def __new__(cls, *args, **kwargs):
print('this is A __new__')
return super(A, cls).__new__(cls)
def __init__(self, title):
print('this is A __init__')
self.title = title
class B(A):
def __new__(cls, *args, **kwargs):
print('this is B __new__')
return super(A, cls).__new__(cls) # 或者下面return的方式
# return object.__new__(cls)
def __init__(self, title):
print('this is B __init__')
self.title = title
b = B('python book')
输出结果:
this is B __new__
this is B __init__
如果子类重写__new__
方法时,return super(子类,cls),那么会调用父类的__new__
方法构造类的实例;文章来源:https://www.toymoban.com/news/detail-450649.html
class A():
def __new__(cls, *args, **kwargs):
print('this is A __new__')
return super(A, cls).__new__(cls)
def __init__(self, title):
print('this is A __init__')
self.title = title
class B(A):
def __new__(cls, *args, **kwargs):
print('this is B __new__')
return super(B, cls).__new__(cls)
def __init__(self, title):
print('this is B __init__')
self.title = title
b = B('python book')
输出结果:文章来源地址https://www.toymoban.com/news/detail-450649.html
this is B __new__
this is A __new__
this is B __init__
到了这里,关于python常见面试题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!