Python期末样题分析
判断题
已知 x = [3],那么执行语句 x = x+ [6] 之后,x的内存地址不改变。(×)
具体分析:
-
初始时,x = [3]。此时x指向一个包含元素 [3] 的列表对象
-
执行
x = x + [6]
-
表达式 x + [6] 会生成一个新的列表 [3, 6],这个新列表存储在新的内存地址(假设为地址 B)。
-
然后,x 被重新绑定到这个新列表,地址从 A 改为 B。
- 如果希望在原列表上进行修改而不改变地址
x.append(6)
或x.extend([6])
,会直接修改原列表,而不创建新的对象
- 二者核心区别
-
表达式 x + [6] 的意思是将两个列表合并生成一个新列表。x = ... 是重新绑定变量,改变了 x 指向的内存地址。
-
列表是一个 可变对象,append 和 extend 修改的是原对象。内存地址保持不变。
Python 变量使用前必须先声明,并且一旦声明仍然可在当前作用域内改变其 类型。(×)
- Python 中变量不需要显式声明
-
Python 是动态类型语言,变量在第一次赋值时自动声明
-
如果在赋值前使用变量,会抛出 NameError,因为变量尚未绑定到任何值。
- 变量的类型可以改变
-
Python 中变量是动态类型,意味着同一个变量名可以绑定不同类型的值。
-
变量名只是一个引用,可以随时重新指向不同类型的对象。
对于a=[1,2]和b=(1,2)两个数据对象而言,a所占内存大于b所占的内存。(√)
- 列表是动态可变的,而元组是不可变的,这使得列表通常会占用比元组更多的内存。
- 列表会预先分配额外的存储空间,用于容纳将来可能添加的元素。
Python支持多继承,如果不同父类中有相同的方法名,则Python解释器报错。(×)
- Python 支持多继承,当不同父类中有相同的方法名时,Python 不会报错,而是会按照一定的规则来决定调用哪个父类的方法
字典属于Python有序序列,和列表、字符串、元组一样都支持双向索引。(×)
- 字典是无序的
-
字典的元素是无序的,不能保证元素的顺序。
-
从 Python 3.7 开始,字典保持插入顺序,但它仍然是无序的数据结构,并不能像列表、元组那样支持通过索引访问。
- 字典的访问方式
-
通过键来访问字典的值,而不是通过索引。
-
字典不支持双向索引(即通过正向和反向的整数索引访问),只能通过键来查找对应的值。
- 列表、元组、字符串的双向索引
列表、元组和字符串是有序的,可以通过整数索引来访问其中的元素,而且支持正向和反向索引。
lst = [10, 20, 30]
print(lst[0]) # 正向索引,输出:10
print(lst[-1]) # 反向索引,输出:30
扩展库os中的方法remove()不可以删除带有只读属性的文件。(√)
-
os.remove() 无法删除带有只读属性的文件,会抛出 PermissionError。
-
需要先改变文件的属性(如使用 os.chmod() 或操作系统工具)来删除只读文件。
使用内置函数open()且以”w”模式打开的文件,文件指针默认指向文件头。()
- "w" 模式
-
表示以写模式打开文件。如果文件不存在,Python 会创建一个新的空文件;如果文件已存在,文件内容会被清空,准备写入新的内容。
-
在这种模式下,文件指针(即当前写入位置)会被设置为文件的开头位置。换句话说,任何写入操作都会从文件头开始,覆盖原有内容。
- 其它模式
-
"a" 模式:以追加模式打开文件,文件指针指向文件末尾,新的内容会添加到文件的现有内容后
-
"r" 模式:以只读模式打开文件,文件指针指向文件头,但不会修改文件内容。
Python 中的列表被切片后,列表中的某个元素被删除后别的元素将不再自动收缩补齐空格。(√)
- 列表切片
- 列表切片会产生一个新的列表,该列表是原始列表中某一部分的副本。切片不会改变原始列表本身
- 删除元素
-
如果删除原始列表中的某个元素,原始列表的大小会减小,后续元素会自动填补删除位置,索引会向前调整,没有“空白”或空槽出现在列表中。
-
但是,切片后的新列表中的元素不会收缩,即它仍然保持原来切片时的元素值,和原始列表的删除操作无关。
语法C=“ab”+“ab”比“ab”.append(“ab”)更快。(√)
- 字符串拼接
-
字符串是不可变对象(immutable),这意味着每次进行字符串操作时(如拼接、连接),都会生成一个新的字符串对象。
-
"ab" + "ab" 实际上会创建一个新的字符串对象 "abab",这是一种非常高效的操作,因为字符串拼接本质上是直接在内存中分配新的空间来存储结果。
这类操作在 Python 中是通过 复制 两个字符串内容来创建新字符串的。
- append() 方法:
-
append() 是列表的方法,它是用于向列表末尾添加元素。"ab".append("ab") 这种写法会导致错误,因为字符串没有 append() 方法。append() 方法是 列表对象的方法,不适用于字符串。
-
将 "ab" 添加到一个列表中,这种情况下 append() 会使得列表增大,但这个操作的时间复杂度为 O(1),意味着每次添加元素的时间复杂度是常数级别的。
# 列表拼接
lst = ["ab"]
lst.append("ab") # 向列表中添加 'ab'
print(lst) # 输出:['ab', 'ab']
单选题
- 关于while循环和for循环的区别,下列说法正确的是(C)。
A.while 语句的循环体至少无条件执行一次,for语句的循环体有可能一次都不执行
B.while 语句智能由于循环次数未知的循环,for语句只能用于循环次数已知的循环
C.在很多情况下,while语句和for语句可以等价使用
D.while 语句只能用于可迭代变量,for语句可以用任意表达式表示条件
A. while只有条件为真时才开始循环,如果条件一开始为假,循环体也不会执行一次。for 循环遍历的是一个可迭代对象,如果可迭代对象为空,那么 for 循环体也不会执行。 所以,while 和 for 都有可能不执行循环体。
# 可迭代对象为空
# 1. 空列表
#一个空列表没有任何元素,迭代时不会进入循环体。
for item in []:
print(item) # 不会执行
# 2. 空元组
#空元组也没有任何元素,迭代时也不会执行循环体。
for item in ():
print(item) # 不会执行
# 3. 空字符串
#空字符串没有字符,迭代时也不会进入循环体。
for char in "":
print(char) # 不会执行
# 4.空字典
#空字典没有键值对,迭代时不会有任何项被返回。
for key in {}:
print(key) # 不会执行
# 5.空集合
#空集合没有任何元素,迭代时不会执行循环体。
for item in set():
print(item) # 不会执行
- 设 str = ‘python’,想把字符串的最后一个字母大写,其他字母还是小写,正确的选项是(D)。
A. print(str[end].upper()+str[1:])
C. print(str[5].upper()+str[1:-1])
B. print(str[6].upper()+str[-1:1])
D. print(str[0:-1]+str[5].upper())
A. print(str[end].upper()+str[1:])
# end不是有效索引,应该是-1来表示最后一个字符。这段代码会抛出NameError
B. print(str[6].upper()+str[-1:1])
# str[6] 超出了有效索引范围,'python' 的最后一个字符是str[5],所以 str[6] 会抛出 IndexError。
C. print(str[5].upper()+str[1:-1])
# 虽然 str[5].upper() 会把最后一个字母 'n' 转换为大写,但是 str[1:-1] 会输出 'ytho'(即从索引 1 到倒数第二个字符),缺少最后一个字母 n。且顺序错误
D. print(str[0:-1]+str[5].upper())
- 以下关于列表操作的描述,错误的是(D)。
A. 通过 append 方法可以向列表添加元素
B. 通过 extend 方法可以将另一个列表中的元素逐一添加到列表中
C. 通过 insert(index,object) 方法在指定位置 index 前插入元素 object
D. 通过 add 方法可以向列表添加元素
- A. 通过 append 方法可以向列表添加元素
lst = [1, 2, 3]
lst.append(4) # 添加元素 4
print(lst) # 输出:[1, 2, 3, 4]
- B. 通过 extend 方法可以将另一个列表中的元素逐一添加到列表中
lst1 = [1, 2]
lst2 = [3, 4]
lst1.extend(lst2) # 将 lst2 中的元素逐一添加到 lst1
print(lst1) # 输出:[1, 2, 3, 4]
- C. 通过 insert(index,object) 方法在指定位置 index 前插入元素 object
如果 index 是负数,它从列表的末尾倒数。
lst = [1, 2, 3]
lst.insert(1, 10) # 在索引 1 处插入元素 10
print(lst) # 输出:[1, 10, 2, 3]
- D. 通过 add 方法可以向列表添加元素
add() 方法是用于 集合 (set) 的方法,不适用于列表。
lst = [1, 2, 3]
# lst.add(4) # 会抛出错误 AttributeError: 'list' object has no attribute 'add'
# 创建一个集合
s = {1, 2, 3}
# 使用 add() 方法添加一个元素
s.add(4)
# 打印集合
print(s) # 输出: {1, 2, 3, 4}
# 添加一个已经存在的元素
s.add(2)
# 集合中的元素仍然保持唯一,不会重复
print(s) # 输出: {1, 2, 3, 4} (没有重复 2)
- 关于面向对象的继承,以下选项中描述错误的是(A)。
A.继承是指一组对象所具有的部分相似性质
B.继承是指类之间共享属性和操作的机制
C.继承是指各类之间的共同性质
D.继承是指一个类具有另一个类的性质
- A. 继承是指一组对象所具有的部分相似性质
错误。继承是指类和类之间的关系,而不是“对象”之间的类似的性质。继承能够让子类从弗雷继承属性和方法,而对象是类的实例,继承描述的是类之间的共享关系,而不是对象之间的相似性
- 关于Python内存管理,下列说法错误的是(B)。 A、变量不必事先声明
B、变量无须先创建和赋值而直接使用
C、变量无须指定类型
D、可以使用del释放资源
- B、变量无须先创建和赋值而直接使用
错误。在 Python 中,变量必须在使用之前先进行赋值。否则会抛出 NameError 错误,因为该变量还没有被定义或创建。
- 关于以下程序输出的两个值的描述正确的是(D)。
da = [1,2,3]
print(id(da))
def getda(st):
fa = da.copy()
print(id(fa))
getda(da)
A. 两个值相等
C. 首次不相等
B. 每次执行的结果不确定
D. 两个值不相等
- print(id(da)):
打印 da 变量的内存地址,即列表 [1, 2, 3] 的内存地址。此时,da 的内存地址已经确定。
- 形参
st 形参没有被使用,全局变量 da 直接使用
- fa = da.copy():
在函数 getda 内部,da.copy() 创建了 da 列表的副本,并将副本赋值给 fa。此时,fa 是一个新创建的列表,其内容与 da 完全相同,但它们是两个独立的对象。
- print(id(fa)):
打印 fa 变量的内存地址。由于 fa 是 da 的副本,fa 和 da 在内存中是两个不同的对象,所以它们的内存地址不同。
- 对于列表ls的操作,以下选项中描述错误的是( )。
A. ls.clear():删除 ls 的最后一个元素
B. ls.copy():生成一个新列表,复制ls的所有元素
C. ls.reverse():列表 ls 的所有元素反转
D. ls.append(x):在 ls 最后增加一个元素
- A. ls.clear():
错误。clear() 方法用于清空整个列表,即删除列表中的所有元素,而不是仅删除最后一个元素。调用 ls.clear() 后,列表 ls 将变为空列表。
- C. ls.reverse():
正确。reverse() 方法用于 反转 列表中元素的顺序,这会修改原列表。
- 现有代码t=(‘a’),在python3解释器中查看type(t)得到的结果为(A)。
A <class ‘str’>
C (class ‘str’)
B <class ‘tuple’>
D (class ‘tuple’)
t = ('a')
t = ('a') 在 Python 中实际上会被解释为一个 字符串。原因是 Python 中只有一个元素的元组必须加上逗号。例如,t = ('a',) 才是一个元组。
因此,t = ('a') 实际上是等价于 t = 'a',即 t 是一个字符串。
- 以下不能创建一个字典的语句是 ( )
A、dict1 = {}
B、dict2 = { 3 : 5 }
C、dict3 = dict( [2 , 5] ,[ 3 , 4 ] )
D、dict4 = dict( ( [1,2],[3,4] ) )
- B. dict2 = {3 : 5}
正确。这是创建一个字典并初始化一个键值对 3: 5 的方式。字典中的键值对可以通过冒号 : 来指定。
- C. dict3 = dict( [2 , 5] , [ 3 , 4 ] )
错误。这是无效的语法,因为 dict() 函数接受一个 可迭代对象(如列表或元组)作为参数,表示键值对的元组。你传入的是两个单独的列表,这会导致语法错误。
- D. dict4 = dict( ( [1, 2] , [3, 4] ) )
正确。这是有效的语法,创建字典的方式是通过 dict() 函数传入一个 包含元组 的列表。这里 ([1, 2], [3, 4]) 实际上是创建了一个包含键值对 (1, 2) 和 (3, 4) 的元组,最终返回的字典是 {1: 2, 3: 4}。
填空题
- 已知列表 x = [(1), 2],执行语句 y = x[1] 后,表达式 id(x[1]) == id(y) 的值 为____True____。
x[1] 和 y 都指向整数 2。
在 Python 中,整数是不可变对象,并且对于小整数(通常在 -5 到 256 之间),Python 会重用相同的对象。这意味着,x[1] 和 y 都指向同一个整数对象 2。
- 表达式 (i for i in range(10) if i>2) 的值为____3、4、5、6、7、8、9____。
-
range(10) 生成一个从 0 到 9 的整数序列。
-
for i in range(10) 表示遍历 range(10) 中的每个整数。
-
if i > 2 是一个条件过滤器,意味着只选取大于 2 的元素。
- 已知 x = [1, 2, 1],那么表达式 id(x[0]) == id(x[2]) 的值为____True____。
- 表达式 eval("import math; math.sqrt(3
**
2 + 4**
2)") 的值为______5______。
- **2表示平方
- 使用列表推导式得到 100 以内所有能被 17 整除的数的代码可以写作____[x for x in range(1, 101) if x % 17 == 0]____。
- 表达式 list(filter(lambda x:x>3, [0,1,2,3,0,0])) 的值为________。
- filter() 函数:
filter(function, iterable)
function:一个函数,用于对 iterable 中的每个元素进行判断,返回 True 或 False。
iterable:一个可迭代对象(例如列表、元组等),会对这个对象中的每个元素进行过滤。
filter() 函数返回一个迭代器,包含所有使得 function 返回 True 的元素。
- lambda 函数:
是 Python 中用于创建匿名函数的关键字。lambda 函数通常用于需要一个小型函数并且不想给它命名的场合。
lambda arguments: expression
arguments:函数的参数。
expression:函数体,返回值会是 expression 的计算结果。
- 假设有Python程序文件demo.py,代码如下:
def main():
if __name__ == '__main__':
print(1)
else:
print(2)
main()
将该程序文件直接运行时输出结果为____1____,作为模块导入时得到结果____2____。
__name__
变量
-
name 是一个特殊的内置变量,它用于表示当前模块的名字。
-
当一个 Python 文件被直接运行时,name 的值会被设置为 'main'。
-
当一个 Python 文件作为模块导入时,name 的值会被设置为该模块的名称。
- if name == 'main'
-
当一个文件被直接运行时,name == 'main' 为 True,所以该代码块会被执行。
-
当该文件作为模块被导入时,name 被设置为模块的名字,条件 name == 'main' 为 False,该代码块不会执行。
- 表达式 list(map(lambda x: len(x), [‘[1,2]’, ‘bb’, ‘ccc’])) 的值为___[6, 2, 3]____。
- map() 函数
map() 是 Python 内置的一个高阶函数,它将指定函数应用于给定可迭代对象的每一个元素,并返回一个迭代器。它的基本语法是:
map(function, iterable, ...)
-
function:一个函数,用于对 iterable 中的每个元素进行操作。
-
iterable:一个或多个可迭代对象(如列表、元组、字符串等),这些对象的元素会依次传递给 function。
返回值:map() 返回一个迭代器,你需要将它转换为列表或其他可迭代类型,才能查看结果。
- len() 函数
len() 是一个内置函数,用于返回对象(如字符串、列表、元组等)的长度或元素个数。它的语法如下:
- list() 函数
list() 是 Python 中的一个内置函数,它将其他可迭代对象(如元组、字典、集合等)转换为列表。如果传入的参数已经是列表,list() 会返回一个新的列表副本。
- map() 与 filter() 的区别
-
map() 用于对每个元素进行操作并返回结果,可以改变元素。
-
filter() 用于对每个元素进行条件判断,并返回那些符合条件的元素。
- 表达式len(‘hello world’[2:])的值为____9____。
它包含 9 个字符:l, l, o, ' '(空格), w, o, r, l, d。
程序分析题
1.将函数补充完整,使其具有以下功能:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出差为目标值的两个整数,并返回他们的数组下标。
给定 nums = [2, 7, 11, 15], target = -9,nums[0] - nums[1] = 2 - 11 = -9,所 以返回 (0, 3)。
def twoDiff(nums, target):
for i in range(len(nums)):
for j in range(i,len(nums)):
____________________
return i,i+j
return False
if nums[i]-nums[j]==target:
2.下列程序的输出结果为:3。
class Student(object):
count = 0
def __init__(self, name, age):
self.name = name
self.age = age
if age > 18
Student.count += 1
@staticmethod
def count_student():
print(共实例%d 个对象' % Student.count)
bob = Student('bob', 19)
Jenny = Student('Jenny', 18)
Danny = Student('Danny', 19)
liming = Student('liming', 20)
Student.count_student()
3.下列程序的输出结果是____1 (换行) 2____。
def generator_example():
yield 1
yield 2
if __name__ == '__main__':
for e in generator_example():
print(e)
- yield 关键字用于生成一个生成器,生成器会逐个返回值,每次返回一个值时,生成器会“暂停”,等待下次继续执行。
4.下列程序表示计算员工工资,工资与工龄有关,计算公式为 salary = 4000 + 200 * age, 输出更改前后的工资。现有一员工jack,原始工龄为4,现在工龄为5,请补充程序空缺:
class Worker:
def __init__(self, name, workAge):
self.name = name
self.workAge = workAge
def salary(self):
return ____________________
salary = property(salary)
def dispSalary(self):
print(self.salary)
jack = Worker('jack', 4)
jack.dispSalary()
jack.workAge = 5
jack.dispSalary()
return 4000 + 200 * self.workAge # 工资计算公式
- 给出输出结果____(相同的内存地址)____。
>>>
L = []
>>>
print(id(L))
>>>
259766
>>>
L.append(“l”)
>>>
print(id(L))
编程题
1.冒泡法对列表list=[5,10,6,7,50,2,13,49]排序(10 分)
list = [5,10,6,7,50,2,13]
n=len(list)
for i range(n):
for j range (n-i-1):
if arr[j]>arr[j+1]:
arr[j],arr[j+1]=arr[j+1],arr[j]
print("排序后的列表",list)
2.斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,
F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1。 用函数形式表示 F(N)。(10分)
def fb(n):
if n==0:
return 0
elif n==1:
return 1
else:
return fb(n-1)+fb(n-2)
n=10
print(f"F({n})={fb(n)}")
- 学校在拍年度纪念照时,一般要求学生按照 非递减 的高度顺序排列。请你返回能让所有学生以非递减高度排列的最小必要移动人数。(10分)
示例:如果学生身高记录为heights,而排列位置记为列表的索引
输入:heights = [1,1,4,2,1,3](表示 6 为学生,身高分别为1,1,4,2,1 和 3)
输出:3
解释:
当前学生的排列为:[1,1,4,2,1,3]
目标排列为:[1,1,1,2,3,4],(索引)2、4和5处的学生需要移动。
def sort(arr):
sorted_heights = sorted(heights)
moves=0
for i in range(len(heights)):
if heights[i]!=sorted_heights[i]:
move+=1
return moves
heights = [1, 1, 4, 2, 1, 3]
print(sort(heights))
#python#