CCF-GESP 等级考试 2025年6月认证Python四级真题解析
1 单选题(每题 2 分,共 30 分)
第1题 2025年4月19日在北京举行了一场颇为瞩目的人形机器人半程马拉松赛。比赛期间,跑动着的机器人会利用 身上安装的多个传感器所反馈的数据来调整姿态、保持平衡等,那么这类传感器类似于计算机的( )。
A. 处理器 B. 存储器 C. 输入设备 D. 输出设备
解析:答案:C。所有传感器都用于采集数据,属于输入设备,故选C。
第2题 小杨购置的计算机使用一年后觉得内存不够用了,想购置一个容量更大的内存条,这时需要的内存条是( )。
A. RAM B. ROM C. CACHE D. EPROM
解析:答案:A。内存条属于随机存储器(RAM)。ROM为只读存储器,数据只能读不能写,不能发内存条使用,错误。CACHE为高速缓存,一般集成在CPU中,不能当内存条使用,EPROM为可编程只读存储器,正常情况下只读,相当于ROM,在特定条件下可改写内容,如固化程序、数据等,也不能当内存条使用。故选A。
第3题 执行下面Python代码后,输出的结果是?( )
- s1 = {('a', 1), ('b', 2)}
- s2 = {('b', 2), ('a', 1)}
- t1 = (('a', 1), ('b', 2))
- t2 = (('b', 2), ('a', 1))
- print(s1 == s2, t1 == t2)
A. True False B. False False C. True True D. False True
解析:答案:A。s1、s2为元素为元组的集合,t1、t2为元素为元组的元组。Python集合使用“==”运算符的相等性判断基于它们包含的元素是否相同。由于集合是无序的数据结构,因此两个集合即便元素顺序不同,只要包含的元素相同,Python也会认为它们是相等的,所以s1==s2为True。有序序列按元素从左到右判断,所以t1<t2,即t1==t2为False。故选A。
第4题 执行下面Python代码后,输出的结果是?( )
- def func(*args):
- return sum(args) / len(args)
- result = func(1, 2, 3, 4, 5)
- print(result)
A. 15 B. 3 C. 3.0 D. 报错
解析:答案:C。第1行函数将任意数量的位置参数以元组形式接收参数,当第5行调用函数时,args=(1,2,3,4,5),返回是sum(args)=15除以len(args)=5的结果,在Python中除“/”运算符运算结果为浮点数,所以result=3.0。故选C。
第5题 以下哪个函数调用是合法的?( )
- def func(a, b, *, c, d=0):
- pass
A. func(1, 2, 3, 4) B. func(a=1, 2, c=3) C. func(1, 2, 3, d=4) D. func(1, 2, c=3)
解析:答案:D。在Python中,通过使用“/”和“*”可以强制使用位置传参和关键字传参,让函数调用更加清晰和规范。1.强制使用位置传参:在函数定义时,将参数列表中带有“/”的参数之前的参数称为位置参数,调用这些参数时只能使用位置传参,不能使用关键字传参。这样可以强制调用者按照定义函数时的顺序提供参数值,提高了代码的可读性和可维护性。2.强制使用关键字传参:在函数定义时,将参数列表中带有“*”的参数之后的参数称为关键字参数,调用这些参数时只能使用关键字传参,不能使用位置传参。使用关键字传参可以提高函数调用的可读性,因为函数调用时可以明确指定参数的名称。例如:def func(a, b, /, c, *, d): print("a:", a); print("b:", b); print("c:", c); print("d:", d),参数a、b只能用位置参数传递,d只能用关键字参数传递。所以对于本题c、d只能关键字参数传递,d有默认参数可省略。A.c、d按位置参数传递,错误。B.一旦使用了关键字参数传递,后续不能再用位置参数传递,错误。C.c必须用关键字参数传递,错误。D. a、b可以用位置参数传递,c用关键字参数传递,d缺省,正确。故选D。
第6题 执行下面Python代码后,输出的结果是?( )
- x = 10
- def func():
- x += 1
- return x
- print(func())
A. 10 B. 11 C. 报错 D. None
解析:答案:C。在Python中,x += 1等价为x = x + 1。第4行函数中没有指定x为全局变量,在执行第5行时,赋值号右边用全局变量x没有问题,但x为整形变量是不可变变量,此时会在本地(局部变量)撤消原变量x重建x,因本地不存在变量x会触发 UnboundLocalError(局部变量未定义)错误。故选C。
第7题 执行下面Python代码后,输出的结果是?( )
- func = lambda x: x * 2 if x > 0 else x // 2
- print(func(-4), func(4))
A. 2 -8 B. -2 8 C. -8 2 D. 报错
解析:答案:B。函数为lambda函数,“:”前为参数,“:”后为表达式,函数返回表达式的结果。本题中表达式为三元表达式,条件成立返回if之前的表达式,条件不成立返回else之后的表达式。当用-4调用函数时,x=-4,x>0不成立,返回x//2=-2(其中//为整除);当用4调用函数时,x=4,x>0成立,返回x*2=8。故选B。
第8题 执行下面Python代码后,输出的结果是?( )
- def apply(func, x):
- return func(x)
- def square(n):
- return n * n
- result = apply(square, 4)
- print(result)
A. 16 B. 8 C. 4 D. 报错
解析:答案:A。函数为apply,第1个参数为函数,返回结果为用第2参数为实参调用接收的函数。本题中调用apply(square, 4),相当于调用square(4),结果为16。故选A。
第9题 执行下面Python代码后,会发生什么?( )
- try:
- raise ValueError
- except Exception:
- print("A")
- except ValueError:
- print("B")
A. 打印"A" B. 打印"B" C. 同时打印"A"和"B" D. 报错
解析:答案:A。Python异常处理中的异常继承关系:ValueError是Exception的子类。这意味着所有ValueError异常同时也是Exception异常,except Exception会捕获所有未被其他except子句捕获的异常。Python异常处理中的except子句匹配顺序:会按except子句的声明顺序从上到下依次匹配异常类型。当找到第一个匹配的except子句后,就会执行该块中的代码,而不会继续检查后续的except子句。本题代码执行流程:在try块中主动抛出了一个ValueError异常,Python首先检查第一个except子句except Exception:,由于ValueError是Exception的子类,这个匹配成功,因此会执行print("A"),然后跳过后续的except ValueError:子句。故选A。
第10题 执行下面Python代码后,输出的结果是?( )
- try:
- 1 / 0
- except ValueError:
- print("A")
- else:
- print("B")
- print("C")
A. A C B. B C C. C D. 报错
解析:答案:D。Python异常处理中try:子句抛出异常,except子句捕获指定异常并执行相应异常处理代码块,else:子句为无异常时执行的代码块。本题中try:中1/0抛出ZeroDivisionError异常,except ValueError:不能捕获,因发生异常else:子句也不会执行,由于try...except异常处理程序没能捕获异常,通常会导致程序崩溃并由系统抛出ZeroDivisionError异常,第7行不会被执行。所以选D。
第11题 以下哪个选项可以正确读取文件"data.txt"的全部内容并返回一个字符串?( )
- with open("data.txt", "r") as f:
- content = ________
A. f.readlines() B. f.readline() C. f.read() D. f.read(100)
解析:答案:C。Python用with方式打开文件不需要用close显式关闭文件。f.line()为只读取一行返回字符串;f.lines()为按行读取读取整个文件,返回元素为字符串的列表,每个元素是文件的一行;f.ead(100)读取当前位置开始的100个字节返回字符串;f.ead()读取文件的全部容并返回一个字符串。所以选C。
第12题 以下哪种文件打开模式可以在不截断文件的情况下同时支持读写?( )
A. "w" B. "r+" C. "a" D. "x"
解析:答案:B。"w":写入模式,会截断文件(清空内容),不支持读取。"r+":读写模式,可以在不截断文件的情况下同时支持读写操作。"a":追加模式,只能写入且不会截断文件,但不支持读取。"x":互斥写入模式打开文件,文件不存在时创建,如果文件已经存在,则会抛出一个OSError异常,不支持直接读写。按题意B.符合。所以选B。
第13题 以下哪种排序算法的时间复杂度在最坏情况下是O(n²)?( )
A. 冒泡排序 B. 选择排序 C. 插入排序 D. 以上都是
解析:答案:D。冒泡排序、插入排序算法的时间复杂度在最好情况下是O(n),选择排序算法的时间复杂度在最好情况下是O(n²),冒泡排序、插入排序和选择排序算法的时间复杂度在最坏情况下都是O(n²)。所以选D。
第14题 执行以下代码后,输出的结果是?( )
- data = ['apple', 'Banana', 'cherry']
- print(sorted(data))
A. ['apple', 'Banana', 'cherry'] B. ['Banana', 'apple', 'cherry']
C. ['apple', 'cherry', 'Banana'] D. ['cherry', 'Banana', 'apple']
解析:答案:B。Python的sorted()是排序函数,返回序列排序后的列表,默认按字典序排序。'B'<'a'<'c',所以输出为['Banana', 'apple', 'cherry']。故选B。
第15题 给定一个整数数组nums,计算其最长递增子序列的长度。子序列可以不连续,但必须保持原数组的顺序。例如:nums = [10, 9, 2, 5, 3, 7, 101, 18] 的最长递增子序列是 [2, 3, 7, 101] ,长度为 4。
- def length_of_LIS(nums):
- dp = [1] * len(nums) # dp[i] 表示以 nums[i] 结尾的最长递增子序列长度
- for i in range(1, len(nums)):
- for j in range(i):
- if nums[j] < nums[i]:
- dp[i] = ________ # 填空
- return max(dp)
A. dp[j] + 1 B. dp[i] + 1 C. min(dp[i], dp[j] + 1) D. max(dp[i], dp[j] + 1)
解析:答案:D。以数据2, 4, 5, 3, 7为例:A.dp=[1,2,3,2,3],3只算1+1(2<3成立),7只计数的是2+1(3<7成立),错误。B.dp=[1,2,3,2,5],只要前面的数小计数就加1,错误。C.dp=[1,1,1,1,1],因为dp[i]初值为1,结果永远为1,错误。D.dp=[1,2,3,2,4],2,4,5连续,2计数为1,4计数为2,5计数为3,当到数字3是只有2比它小,计数为2,数字7时,5比7小,此时计数为4,到数字3时,3比7小,此时计数为max(4,3)=4,正确。简单地说:A. dp[j] + 1:仅考虑当前j的情况,会覆盖之前可能更大的dp[i]值;B. dp[i] + 1:逻辑错误,会导致错误累加;C. min(dp[i], dp[j] + 1):取最小值,因为dp[i]初值为1,结果永远为1,会得到不正确的更小长度;D. max(dp[i], dp[j] + 1):正确做法,保留最大长度。故选D。
2 判断题(每题 2 分,共 20 分)
第1题 现在,人们参加各种闭卷考试时通常都不允许将智能手机、平板电脑等带入考场,因为智能手表通常都有嵌入操作系统及通信等功能,所以也不允许携带入考场。( )
解析:答案:正确。智能手表因为具有嵌入操作系统及通信等功能,通讯功能风险:1.智能手表普遍具备蓝牙、Wi-Fi或蜂窝网络功能,可实现实时信息收发(如接收答案、传输试题),即使关机或断网,其硬件模块仍存在作弊隐患。2.信息存储与计算能力:可存储公式、文档、图片等考试相关资料,或内置计算器、单位换算等工具,违反"仅依靠知识储备答题"的原则。3.隐蔽性高,监管困难:部分智能手表外观与普通手表相似,监考人员难以快速甄别功能;其屏幕切换、震动提醒等特性可能用于传递作弊信号,所以也不允许随身携带。故正确。
第2题 执行下面Python代码后,输出的结果为3。( )
- data = {'ids': [1, 2], 'name': 'test'}
- data['ids'].extend(['g', 'e', 's', 'p'])
- print(len(data['ids']))
解析:答案:错误。列表的append方法用于在列表末尾添加单个元素(支持任意类型数据)。extend方法用于将可迭代对象(如序列、迭代函数等)的元素逐个添加到原列表末尾,不会嵌套。第2行的'g', 'e', 's', 'p'4个元素会添加到[1, 2]的尾部,即'ids': [1, 2, 'g', 'e', 's', 'p'],所以len(data['ids'])=6,即输出的结果为6不为3。故错误。
第3题 执行下面Python代码会报错,因为lambda函数不能有默认参数。( )
- f = lambda x, y=2: x + y
- f(1)
解析:答案:错误。lambda函数(即匿名函数)只是写成一行的函数,形参写在“:”之前,只能有一个返回表达式写在“:”之后,形参的要求与普通函数相同,故可以有默认参数,也可用*x、**y形式的参数。故错误。
第4题 执行下面Python代码后,输出的结果为 [1, 4, 9] 。( )
- print(list(map(lambda x: x**2, [1, 2, 3])))
解析:答案:正确。map函数的第1参数为函数名(可以是自定义函数名和lambda函数),第2参数为序列,如元组、列表等,返回一个迭代器(map对象),遍历序列的每个元素,并用第1参数指定函数处理的结果,可用list()转换为列表。本题处理函数为求平方,元素1、2、3经平方后输出为1、4、9,转列表后输出为[1, 4, 9]。故正确。
第5题 执行下面Python代码后,将只输出 try 。( )
- def test():
- try:
- return "try"
- finally:
- print("finally执行了")
- print(test())
解析:答案:错误。Python的异常处理,try语句块中如出现异常,会被except子句捕获,如try语句块中不出现异常则会执行else子句语句块(如果存在的话),如果存在finally子句,不论是否出现异常都会执行相应语句块。对本题第7行调用函数test(),test函数的try语句块不发生异常,test函数在返回"try"的同时输出"finally执行了",然后第7行输出返回结果"try"。所以输出为两行,第1行finally执行了,第2行try。故错误。
第6题 在Python中, readlines() 方法返回的文件内容包含每行末尾的换行符( \n )。( )
解析:答案:正确。Python中的文本文件读取方法readline()、readlines()方法都包含行末尾的换行符( \n )。故正确。
第7题 递推算法的核心思想是利用已知条件逐步推导后续结果。( )
解析:答案:正确。Python中的文本文件读取方法readline()、readlines()方法都包含行末尾的换行符( \n )。故正确。
第8题 选择排序是一种稳定的排序算法。( )
解析:答案:错误。选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。举个例子,序列5 8 5 2 9,第一趟选择第1个元素5会和2交换,那么原序列中两个5的相对前后顺序就被破坏了,所以选择排序是一个不稳定的排序算法。故错误。
第9题 以下代码的时间复杂度是 O(n) 。
- def func(n):
- for i in range(n):
- for j in range(n):
- print(i, j)
解析:答案:错误。程序双重循环,时间复杂度是 O(n²),所以时间复杂度不是O(n)。故错误。
第 10 题 以下代码的空间复杂度是 O(1) 。
- def sum_elements(arr):
- total = 0
- for num in arr:
- total += num
- return total
解析:答案:正确。程序只用了有限个变量total、num,所以空间复杂度是 O(1)。故正确。
3 编程题(每题 25 分,共 50 分)
3.1 编程题1
- 试题名称:画布裁剪
- 时间限制:3.0 s
- 内存限制:512.0 MB
3.1.1 题目描述
小A在高为h宽为w的矩形画布上绘制了一幅画。由于画布边缘留白太多,小A想适当地裁剪画布,只保留画的主体。具体来说,画布可以视为h行w列的字符矩阵,其中的字符均为ASCII码位于33~126之间的可见字符,小A只保留画布中由第x₁行到第x₂行、第y₁列到第y₂列构成的子矩阵。
小A将画布交给了你,你能帮他完成画布的裁剪吗?
3.1.2 输入格式
第一行,两个正整数h,w,分别表示画布的行数与列数。
第二行,四个正整数x₁,x₂,y₁,y₂,表示保留的行列边界。
接下来h行,每行一个长度为w的字符串,表示画布内容。
3.1.3 输出格式
输出共x₂-x₁+1行,每行一个长度为y₂-y₁+1的字符串,表示裁剪后的画布。
3.1.4 样例
3.1.4.1 输入样例1
- 3 5
- 2 2 2 4
- .....
- .>_<. ..... ><.
- .....
3.1.4.2 输出样例1
- >_<. ..... ><
3.1.4.3 输入样例2
- 5 5
- 1 2 3 4
- AbCdE
- fGhIk
- LmNoP
- qRsTu
- VwXyZ
3.1.4.4 输出样例2
- Cd
- hI
3.1.5 数据范围
对于所有测试点,保证1≤h,w≤100,1≤x₁,x₂≤h,1≤y₁,y₂≤w。
3.1.6 编写程序思路
分析:本题可以用列表来做,列表的元素为字符串,行为列表元素、列为字符串。按行、列输入n行、m列字符(画布),然后截取x1、y1到x2、y2范围内的元素输出。行的截取用循环,列的截取用字符串的切片操作,行row从x1-1循环到x2,列从y1-1列到y2列(字符串索引从0开始)。可用多种方法输入数据,完整程序代码如下:
方法一:用map()处理数据,输入画布数据用.append()方法添加到列表
n, m = map(int, input().split())
x1, x2, y1, y2 = map(int, input().split())
a = []
for _ in range(n): #输入n行画布数据a.append(input().strip()) #strip()防首尾空白字符
for i in range(x1-1, x2): #行从x1到x2(行索引从0开始,range不含终点x2)print(a[i][y1-1:y2]) #列从y1到y2(列索引从0开始,切片不含终点y2)
方法二:用列表推导式处理输入数据,包括画布数据
n, m = [int(i) for i in input().split()]
x1, x2, y1, y2 = [int(i) for i in input().split()]
a = [input().strip() for _ in range(n)] #输入n行,strip()防首尾空白字符
for i in range(x1-1, x2): #行从x1到x2(行索引从0开始,range不含终点x2)print(a[i][y1-1:y2]) #列从y1到y2(列索引从0开始,切片不含终点y2)
3.2 编程题
- 试题名称:排序
- 时间限制:3.0 s
- 内存限制:512.0 MB
3.2.1 题目描述
体育课上有n名同学排成一队,从前往后数第i位同学的身高为h,体重为w。目前排成的队伍看起来参差不齐,老师希望同学们能按照身高从高到低的顺序排队,如果身高相同则按照体重从重到轻排序。在调整队伍时,每次只能交换相邻两位同学的位置。老师想知道,最少需要多少次交换操作,才能将队伍调整成目标顺序。
3.2.2 输入格式
第一行,一个正整数n,表示队伍人数。
接下来n行,每行两个正整数hᵢ和wᵢ,分别表示第i位同学的身高和体重。
3.2.3 输出格式
输出一行,一个整数,表示最少需要的交换次数。
3.2.4 样例
3.2.4.1 输入样例1
- 5
- 1 60
- 3 70
- 2 80
- 4 55
- 4 50
3.2.4.2 输出样例1
- 8
3.2.4.3 输入样例2
- 5
- 4 0
- 4 0
- 2 0
- 3 0
- 1 0
3.2.4.4 输出样例2
- 1
3.2.5 数据范围
对于所有测试点,保证1≤n≤3000,hᵢ,wᵢ≤10⁹。
3.2.6 编写程序思路
分析:本题是成对的数据,可用数据对元组的列表,也可用数据对列表的列表。排序可用冒泡法。类选择排序。完整程序代码如下:
方法一:输入转数据对元组的列表,用冒泡法排序
n = int(input()) #输入人数
s = []
for _ in range(n): #输入n人h, w = [int(i) for i in input().split()] #输入身高、体重对s.append((h, w)) #身高、体重对元组作为元素添加到列表
cnt = 0 #统计最终的交换次数
for i in range(n-1): #冒泡排序法排序for j in range(0,n-i-1):if s[j][0] < s[j+1][0] or (s[j][0] == s[j+1][0] and s[j][1] < s[j+1][1]):s[j], s[j+1] = s[j+1], s[j]cnt += 1; #满足交换条件统计数加1
print(cnt)
方法二:输入转数据对列表的列表,用类选择排序法排序
n = int(input()) #输入人数
s = []
for _ in range(n): #输入n人s.append([int(i) for i in input().split()]) #身高、体重对列表作为元素添加到列表
cnt = 0 #统计最终的交换次数
for i in range(n-1):for j in range(i+1, n):if s[i][0] < s[j][0] or (s[i][0] == s[j][0] and s[i][1] < s[j][1]):s[i], s[j] = s[j], s[i] #一轮下来s[i]为s[j]中的最大值(降序)cnt += 1; #满足交换条件统计数加1
print(cnt)