1. is
和 ==
的区别
==
用于比较两个对象的值是否相等。
a=[1,2]
b=[1,2]
print(a==b) #输出 True
is
用于比较两个对象是否是同一个对象(即它们的内存地址是否相同)。
a=[1,2]
b=a
c=[1,2]
print(a is b) # 输出 True
print(a is c) # 输出 False
2.一行代码实现 1 - 100 求和
可以使用 Python 内置的 sum()
函数和 range()
函数:
print(sum(range(1,101))) # 输出 5050
3. 如何修改全局变量?global
关键字作用
在 Python 中,如果要在函数内部修改全局变量,需要使用 global
关键字声明该变量为全局变量。
num=10
def change_num():
global num
num=13
change_num()
print(num) # 输出 13
global
关键字的作用是在函数内部声明一个变量为全局变量,这样在函数内部就可以对该全局变量进行修改。
4.解释 *args
和 **kwargs
的用法
*args
(非关键字可变参数)用于在函数定义中接收任意数量的位置参数,这些参数会被打包成一个元组。
def func(*args):
for arg in args:
print(arg)
func(1, 2, 3, 'q', 'w', 'e') # 返回 1 2 3 q w e
**kwargs
(关键字可变参数)用于在函数定义中接收任意数量的关键字参数,这些参数会被打包成一个字典。
def func(**kwargs):
for key,value in kwargs.items():
print(f"{key}:{value}")
func(name='xiaomao',age=1,breeds='caili') # 返回 name:xiaomao
# age:1
# breeds:caili
5.如何检查变量类型?type()
和 isinstance()
区别
- 检查变量类型可以使用
type()
函数和isinstance()
函数。 type()
函数返回变量的类型。
name = 'xiaomao'
age = 1
print(type(name)) # 输出 <class 'str'>
print(type(age)) # 输出 <class 'int'>
isinstance()
函数用于检查一个对象是否是某个类(或其子类)的实例。
class A:
pass
class B(A):
pass
C = B()
print(isinstance(C, B)) # 输出 True
print(isinstance(C, A)) # 输出 True
print(type(C) == B) # 输出 True
print(type(C) == A) # 输出 False
区别:type()
不会考虑继承关系,而 isinstance()
会考虑继承关系。
6.字典如何删除键?合并两个字典的方法
- 删除键:可以使用
del
语句或pop()
方法。
dict1 = {'a': 1,'b': 2,'c':3}
del dict1['a']
print(dict1) # 输出 {'b': 2, 'c': 3}
dict1.pop('b')
print(dict1) # 输出 {'c': 3}
- 合并两个字典:
方法一:使用 update()
方法。
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
dict1.update(dict2)
print(dict1) # 输出 {'a': 1, 'b': 2, 'c': 3, 'd': 4}
方法二:使用字典推导式(Python3.5及以上)。
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
dict3 = {**dict1,**dict2} # 使用 ** 解包字典
print(dict3) # 输出 {'a': 1, 'b': 2, 'c': 3, 'd': 4}
方法三:使用 | 运算符(Python3.9及以上)。
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
dict3 = dict1 | dict2
print(dict3) # 输出 {'a': 1, 'b': 2, 'c': 3, 'd': 4}
如果字典中有重复的键,后面字典中的值会覆盖前面的:
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 9, 'c': 3} # 'b' 键重复
dict3 = dict1 | dict2
print(dict3) # 输出: {'a': 1, 'b': 9, 'c': 3}
7.列表去重的方法
- 方法一:使用集合(
set
),因为集合中的元素是唯一的。
list1 = [1,2,3,5,4,5,4,]
list1 = list(set(list1))
print(list1) # 输出 [1, 2, 3, 4, 5]
注:这种方法会改变列表元素的顺序。
- 方法二:使用列表推导式。
list1 = [1,2,3,5,4,5,4,]
new_list = []
for num in list1:
if num not in new_list:
new_list.append(num)
print(new_list) # 输出 [1, 2, 3, 5, 4]
这种方法可以保持列表元素的顺序。
8.使用 map()
函数将 [1,2,3,4,5]
转为 [1,4,9,16,25]
- 法一:定义一个函数,将每个元素进行平方操作,然后使用
map()
函数。
def square(x):
return x**2
list1 = [1,2,3,4,5]
result = list(map(square, list1))
print(result) # 输出 [1, 4, 9, 16, 25]
- 法二:使用 lambda 函数:
list1 = [1, 2, 3, 4, 5]
result = list(map(lambda x: x ** 2, list1))
print(result) # 输出 [1, 4, 9, 16, 25]
9.生成随机整数、小数的方法
- 生成随机整数:使用
random
模块中的randint()
函数。
import random
random_int = random.randint(1,100) # 生成1到100之间的随机整数
print(random_int)
- 生成随机小数:使用
random
模块中的random()
函数(生成 0 到 1 之间的随机浮点数),或者uniform()
函数(生成指定范围内的随机浮点数)。
import random
random_float1 = random.random() # 生成0到1之间的随机小数
print(random_float1)
# 生成指定范围内的随机浮点数
random_float2 = random.uniform(1,10) # 生成1到10之间的随机小数
print(random_float2)
# 生成随机浮点数并保留指定小数位数
random_float3 = round(random.uniform(0, 100), 2) # 保留2位小数
print(random_float3)
10.字符串插值的 3 种方式
- 方法一:使用
%
格式化。 - 方法二:使用
format()
方法。 - 方法三:使用 f - strings(Python 3.6 及以上)。
name = 'Mimi'
age = 1
breed = 'sanhua'
# 使用% 格式化
print("The cat's name is %s, %d years old, and its breed is %s." % (name, age,breed))
#使用 format()
print("The cat's name is {}, {} years old, and its breed is {}." .format(name, age,breed))
#使用 f-strings
print(f"The cat's name is {name}, {age} years old, and its breed is {breed}.")
# 输出 The cat's name is Mimi, 1 years old, and its breed is sanhua.
11.解释 Python 的命名空间和作用域
- 命名空间:是从名称到对象的映射,用于避免名称冲突。Python 中有多种命名空间,如内置命名空间(包含 Python 内置函数和对象的名称)、全局命名空间(模块级别的名称)、局部命名空间(函数或类内部的名称)等。
- 作用域:是程序中命名空间可被直接访问的区域。Python 有四种作用域:局部作用域(函数内部)、嵌套作用域(嵌套函数内部)、全局作用域(模块级别)、内置作用域(Python 内置名称)。当在某个作用域中引用一个名称时,Python 会按照局部、嵌套、全局、内置的顺序查找该名称。
12.列表和元组的区别及使用场景
- 区别:
- 列表是可变的,可以对其进行增、删、改等操作;元组是不可变的,一旦创建,不能修改其元素。
- 列表使用方括号
[]
定义;元组使用圆括号()
定义(也可以省略括号)。
- 使用场景:
- 当数据需要频繁修改时,使用列表。
- 当数据不希望被修改,或者需要作为字典的键、在集合中使用时,使用元组。
13.正则匹配 <div class="nam">中国</div>
中 “中国”
可以使用正则表达式来匹配。例如:
import re
# 导入正则表达式模块re,处理字符串的正则匹配操作
html = '<div class="nam">中国</div>'
pattern = r'<div class="nam">(.*?)</div>' # (.*?) 非贪婪匹配捕获中间的内容
result = re.search(pattern, html)
if result:
print(result.group(1)) # 输出 中国
(.*)
是贪婪匹配:会尽可能匹配最长的符合条件的字符串,直到无法继续匹配为止。
例如,对于字符串 <div>内容1</div><div>内容2</div>
,使用 <div>(.*)</div>
匹配时:会从第一个 <div>
开始,一直匹配到最后一个 </div>
,结果会包含 内容1</div><div>内容2
。
-
(.*?)
是非贪婪(惰性)匹配:会尽可能匹配最短的符合条件的字符串,一旦找到第一个满足条件的结束位置就停止。
同样对于字符串<div>内容1</div><div>内容2</div>
,使用 <div>(.*?)</div>
匹配时:会匹配第一个 <div>
到第一个 </div>
,结果仅包含 内容1
。
总结:贪婪匹配(.*
):"饿狼扑食",尽可能多吃
非贪婪匹配(.*?
):"浅尝辄止",见好就收
在提取成对标签内的内容(如 HTML、XML)时,通常需要用非贪婪匹配(.*?
)来精确获取目标内容。
14. 可变类型与不可变类型的区别
- 不可变类型:对象创建后,其值不能被修改。如果对不可变对象进行 “修改” 操作,实际上是创建了一个新的对象。常见的不可变类型有
int
、float
、str
、tuple
等。
- 可变类型:对象创建后,其值可以被修改,修改操作不会创建新的对象。常见的可变类型有
list
、dict
、set
等。
使用 id()
函数查看对象身份:
# 不可变类型示例
a = "hello"
print(f"a初始 id: {id(a)}") # 输出初始内存地址
a = a + " world" # 这里是创建了新的字符串对象,不是修改原对象
print(f"a修改后 id: {id(a)}") # 输出新内存地址,与初始不同
# 可变类型示例
lst = [1, 2, 3]
print(f"列表初始 id: {id(lst)}") # 输出初始内存地址
lst.append(4) # 直接在原列表上添加元素,没有创建新列表
print(f"修改后列表 id: {id(lst)}") # 输出相同的内存地址
使用 is
运算符比较对象身份:
# 不可变类型
a = "hello"
b = a # b 和 a 引用同一个对象
print(a is b) # 输出: True
a = a + " world" # 创建新对象
print(a is b) # 输出: False
# 可变类型
lst1 = [1, 2, 3]
lst2 = lst1 # lst2 和 lst1 引用同一个对象
print(lst1 is lst2) # 输出: True
lst1.append(4) # 修改原对象
print(lst1 is lst2) # 输出: True(仍然是同一个对象)
15. 深拷贝与浅拷贝的区别
- 浅拷贝:只拷贝对象的引用,而不是对象本身。如果原对象中的元素是可变类型,修改拷贝后的对象中的可变元素,原对象也会受到影响。可以使用
copy()
方法实现浅拷贝。
import copy
lst1 = [1, [2, 3]]
lst2 = copy.copy(lst1)
lst2[1].append(4)
print(lst1) # 输出 [1, [2, 3, 4]]
print(lst2) # 输出 [1, [2, 3, 4]]
- 深拷贝:拷贝对象及其所有嵌套对象,是一个完全独立的副本。修改深拷贝后的对象,原对象不会受到影响。可以使用
deepcopy()
方法实现深拷贝。
import copy
lst1 = [1, [2, 3]]
lst2 = copy.deepcopy(lst1)
lst2[1].append(4)
print(lst1) # 输出 [1, [2, 3]]
print(lst2) # 输出 [1, [2, 3, 4]]