2022 年 Python “十级”试题,30 道答案全解析,涨见识了!

发布于:2022/9/1 13:33:54   所属分类:高考备战学习资料库
△点击上方“Python猫” ,回复“1”领取电子书

你好,我是猫哥。上周分享了一篇《2022 年 Python “十级”试题(全国卷A)》,文章很受大家欢迎。原作者还出了 B 卷和 C 卷,题目越来越有趣。今天分享的是作者对全部 30 道题目的完整解析,大家可以看到题目的灵感、出题意图和原理解析,相信会有更多收获~~PS.@古明地觉大佬也写了系列详细的答案解析,可对照阅读(跳转)。

作者:dongwm

来源:https://www.dongwm.com/post/python-ten-level-exam

好久没登录豆瓣,前天上线看到【追剧小露珠】发的 《绝命毒师十级学者统一考试》 ,没事答题发现还挺有趣的,然后,就想到了《Python 十级考试》这个主题,找一些和 Python 有关的、常见但是很可能会被答错的题目写成试卷,结果一准备发现还凑够了三份试题,所以在gongzhong号连续写了三篇:

  1. 2022 年 Python 十级试题 (全国卷 A)
  2. 2022 年 Python 十级试题 (全国卷 B)
  3. 2022 年 Python 十级试题 (全国卷 C)

这些题目的灵感主要来自 wtfpython 和 《Mouse Vs Python》的作者 Mike Driscoll 的 Tweet ,当然我也加了一些自己的私货。

其中第三篇的题目会更难一点,如果你想要试试,可以先通过gongzhong号文章链接进去写写答案。完了再来看我之后写的这篇试题答案和解析。

另外如果我标注了【送分题】的题目你没答对,我建议你找个时间再专注的学一次 Python。

题目 1

先看全国卷 A 的 10 道题目。


这个题目来自 Raymond Hettinger 的 Tweet 。

答案是 B. 因为- 1(中间有空格) 其实就是-1,也就是说可以这么表示score -= (-1)。

题目 2

送分题,答案是 A,也就是抛 SyntaxError 错误,因为海象操作符需要使用括号不能直接用,因为需要和普通的赋值区分开来。

题目 3


题目来源:https://github.com/satwikkansal/wtfpython#-deleting-a-list-item-while-iterating

这个题目主要是考验对迭代的理解。在循环时先迭代了第一个元素 1 (索引 0) 然后 remove 删除这个元素,剩下了三个元素 2,3,4,但是注意,这里 2 的索引是 0,3 的索引是 1。下一次迭代应该是索引 1,就是迭代并删掉 3,把 2 给略过了,接着会把 4 略过。略过的就会留下,所以结果是[2, 4]。

题目 4


送分题,答案是 D,因为min是自带的函数,如果把它替换成其他的对象就不能正常运行了,那么就会抛错 TypeError。

题目 5


题目来源:https://github.com/satwikkansal/wtfpython#-be-careful-with-chained-operations

答案是 A,这个特别反直觉对吧。但要注意比较方式是按顺序把相邻的 2 个分别比较, 官网这么说 :

if a, b, c, …, y, z are expressions and op1, op2, …, opN are comparison operators, then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z, except that each expression is evaluated at most once.

所以False == False in [False]的意思是(False == False) and (False in [False]),所以结果是 True。

题目 6


送分题,答案是 A,因为 bool 值也是一种数字 (True 为 1,False 为 0):

In:isinstance(True,int)
Out:True

In:'haha'*True
Out:'haha'

In:'haha'*False
Out:''

题目 7


答案是 B。这道题我就是想让大家知道判断可以直接在 print 里面写,而不需要这样:

In:a=100

In:result=aifa>100else1

In:print(result)
1

题目 8


送分题,答案是 D,知识点是列表解包 (Unpacking)。

题目 9


题目来源:https://github.com/satwikkansal/wtfpython#-hash-brownies

答案是 C. 在 Python 的字典中,它不关心键的类型,只要它们的值一样那么就是同一个键值对,后面的赋值会替换前面的值:

In:1==1.0
Out:True

题目 10


答案是 A,来源找不到了,我之前还专门写过一篇文章讲这个 一段迷惑的使用海象操作符的代码

题目 11

再看全国卷 B 的 10 道题目。


这个不了解的比较难,答案是 A。这是 Python freeze 自动创建的模块,除此之外还有__phello__:

In:import__hello__
Helloworld!

In:import__phello__
Helloworld!

In:import__phello__#只有第一次import才会执行,之后就【缓存】了。

而其他选项中,__builtin__是 Python 2 时代的模块,还有个 Python2/3 都可以用的 builtins 模块,但是没有__builtins__。另外有__future__和futures但没有__futures__,都是用来混淆的。

题目 12


题目来源:https://github.com/satwikkansal/wtfpython#-needles-in-a-haystack-

答案是 C。这个和题目 10 其实很像。你可以把它理解成这是一个赋值语句,逗号前面的赋值给 x,后面的赋值给 y。如果加上括号就是另外一个意思了:

In:x,y=(0,1)ifTrueelse(None,None)

In:x
Out:0

In:y
Out:1

这样就表示根据判断条件赋值不同的元组了。

题目 13


题目来源:https://github.com/satwikkansal/wtfpython#-the-disappearing-variable-from-outer-scope

答案是 D。而在 Python2 中,e 的结果是Exception(),注意这个和 wtfpython 项目里的说明不符。

在 Python3 为什么直接抛 NameError 呢?因为:

exceptEasN:
foo

在 except 作用域里面实际上相当于:

exceptEasN:
try:
foo
finally:
delN

也就是说,最终在离开作用域时会把 as 的别名 N 删掉,这样 e 就不存在了,所以是 NameError。

题目 14


送分题,答案是 B。这是海象操作符的常见应用场景,首先先在(x := [1, 2])里给 x 赋值为[1, 2],然后再对这个 x 执行x.extend(x)。

题目 15


答案是 A。这个题目是展示在循环时还能做其他很多事情,例如顺便对迭代对象赋值。很久前我还发过类似的 豆瓣广播 :


题目 16


题目来源:https://github.com/satwikkansal/wtfpython#-all-sorted-

答案是 B。这个第一次我也想错了。它的问题在于对一个迭代对象做两次迭代时,后面那次的迭代开始时迭代对象已经为空了:

In:x=7,8,9

In:y=reversed(x)

In:sorted(y),sorted(y)
Out:([7,8,9],[])

题目 17


题目来源:https://github.com/satwikkansal/wtfpython#-same-operands-different-story

送分题,答案是 A。a += [4, 5, 6]会生成新的列表 a,但是 b 引用的是旧的 a,所以不会受到影响。

题目 18


题目来源:https://github.com/satwikkansal/wtfpython#-loop-variables-leaking-out

送分题,答案是 C。for 循环会影响作用域之外的变量值,但是有一点需要注意,从 Python 3 开始,列表解析不会影响作用域之外的变量值,举个例子:

In:x=1

In:print([xforxinrange(5)])
[0,1,2,3,4]

In:x
Out:1#未受到列表解析的影响

题目 19


绝对的送分题,答案是 C。不过这个题目我没写好,原题目对于 Python 熟悉的开发者自动会去掉 A/B2 个答案,应该选项是:

A.{range(0,3)}
B.(range(0,3))
C.{0,1,2}
D.{1,2,3}

这样就更具备迷惑性了。其实就是把一个 range 类型的可迭代对象在集合里面解包。

题目 20


题目来源:https://github.com/satwikkansal/wtfpython#-yielding-from-return-

这个其实是语言设计的问题,答案 C。

首先说yield from其实就是:

foriinrange(x):
yieldi

的意思。主要考验大家对于生成器和 Python 3.3 新加入的yield from的熟悉程度。如果一个函数内有yield或者yield from,那么这就是一个生成器:

In:defa():
...:yield1
...:

In:a()
Out:<generatorobjectaat0x1076aa040>

In:defb():
...:yieldfrom[1,2]
...:

In:b()
Out:<generatorobjectbat0x1051af820>

当时设计时 生成器内可以使用 return ,事实上是停止生成器的用途,如官方所说:

"... return expr in a generator causes StopIteration(expr) to be raised upon exit from the generator."

所以return ['wtf']等于raise StopIteration(['wtf']),在执行list()的时候,就会捕捉错误直接结束。

但是我们这个例子中,直接符合的 return 的条件,就造成它直接返回了空列表 (因为一上来就 raise 了 StopIteration)。

题目 21

最后看全国卷 C 的 10 道题目。这也是我认为最难的一份卷子了。


考验对__future__模块的了解程度,答案是 C。大家应该了解每个选项的意义,我这里就不挨个提了。

题目 22


题目来源:https://github.com/satwikkansal/wtfpython#-name-resolution-ignoring-class-scope

答案是 A。首先,嵌套在类定义中的范围会忽略在类级别绑定的变量。

另外如题目 18 里面提到的,Python 3 的列表解析 / 生成器有自己的作用域,而不会影响外面。

题目 23


题目来源:https://github.com/satwikkansal/wtfpython#-evaluation-time-discrepancy

答案是 C。在生成器表达式中,in是声明时计算,条件判断时在运行时执行计算。所以这个题目中gen = (x for x in array if array.count(x) > 0)也就是gen = (x for x in [1, 8, 15] if [2, 8, 22].count(x) > 0)

这个地方需要大家仔细理解。

题目 24


题目灵感:https://github.com/satwikkansal/wtfpython#-deep-down-were-all-the-same

我们先思考==和is的关系:==表示值相等,is表示指向的内容地址一样,所以对比的 2 个选项可能==但是可能不is,因为is需要更高的要求,同样的,如果is了,那么肯定==。

我们挨个去确定。WTF() == WTF()表示 2 个实例,肯定不会是一样的;WTF() is WTF()既然都不相等,所以is就更不可能了。

如果你理解==和is的关系,现在就可以知道答案是 C。但是为什么id(WTF()) == id(WTF())而id(WTF()) is id(WTF())不对呢?

在一个表达式中,如果执行 2 遍 id 函数,后面那次会被分配到相同内存位置,所以相等==。但是id(WTF()) is id(WTF())其实和本题目关系不大,是我发挥的选项,举个更直接的例子:

In:a=id(0)

In:b=id(0)

In:a
Out:4373539088

In:b
Out:4373539088

In:aisb
Out:False

In:id(0)isid(0)
Out:False

这个是池化的问题,如果数字不在 - 5 到 256 之间,Python 不会缓存数字对象,而 id 函数执行的结果远大于这个值所以就是 False 了。

我们在最新的 Python3.10 试一下,默认的输出不符合预期,我再换个思路:

In:256is256#错误输出
<>:1:SyntaxWarning:"is"withaliteral.Didyoumean"=="?
<ipython-input-1-975396cd1f1b>:1:SyntaxWarning:"is"withaliteral.Didyoumean"=="?
256is256
Out:True

In:257is257#错误输出
<>:1:SyntaxWarning:"is"withaliteral.Didyoumean"=="?
<ipython-input-2-dd70d8dec340>:1:SyntaxWarning:"is"withaliteral.Didyoumean"=="?
257is257
Out:True

In:defadd(n):#我们改个思路
...:returnn+256
...:

In:add(0)isadd(0)#256is256
Out:True

In:add(1)isadd(1)#257is257
Out:False#超过256所以是False了

题目 25


题目来源:https://github.com/satwikkansal/wtfpython#-all-true-ation-

这个其实仔细仔细分析是可以找到答案的,答案为 B。

all的意思是把参数做循环,每个元素都符合要求才是 True,只要有一个不符合就是 False。所以all([])是空列表结果为空,all([[]])表示列表只有一个元素[],而空列表是 False,所以结果是 False。

最后 2 个选项稍微让人迷惑,列表只有一项元素,分别是[[]]和[[[]]],它们都是非空的,所以布尔值是 True:

In:bool([[]])
Out:True

In:bool([[[]]])
Out:True

题目 26


这个相对比较简单,资深的 Python 开发应该会写过这样的代码,答案是 C。

在 Python 中,如果对变量赋值,那么这个变量就会编程当前范围的本地变量,所以在函数some_func里面a += 1,a就成了函数里的本地变量,但是在函数范围里面,前面并没有定义 a 或者对 a 赋值,只有a += 1,所以就抛 UnboundLocalError 了。

如果想让程序不报错,解决办法是在函数内加 global 关键字:

In:a=1

In:defsome_func():
...:globala
...:a+=1
...:returna
...:

In:some_func()
Out:2

但是注意,global 要谨慎使用,如它的名字所提示的,使用它会影响全局变量的结果。

题目 27


答案是 B。这个题目考查对于字符串的strip、rstrip等方法的含义。默认情况下它们是用作去掉字符串行位空格的:

In:'s'.strip()
Out:'s'

In:'s'.rstrip()
Out:'s'

In:'s'.lstrip()
Out:'s'

但是也可以传入其他字符串,实现replace函数所做把对应匹配项替换成空:

In:'s'.rstrip('s')
Out:'s'

In:'s'.rstrip('s')
Out:''

In:'abc'.rstrip('bc')
Out:'a'

所以原字符串中包含的.US.TXT都会被替换,也就是. U S T X这几个字符会被替换成空。

注意,如果只是想要移除后缀,可以使用 Python 3.9 新加入的removesuffix/removeprefix:

In:'WKHSS.US.TXT'.removesuffix('.US.TXT')
Out:'WKHSS'

题目 28


题目来源:https://github.com/satwikkansal/wtfpython#-how-not-to-use-is-operator

答案是 A。这其实是 Python3.7 的一个 BUG,已经在https://bugs.python.org/issue34100里面修复。

题目 29


本题目考验对nonlocal的理解,答案是 D。在前的题目中我们也有所涉及。先看一个例子:

In:i=0
...:
...:defa():
...:i=1
...:print('local:',i)
...:
...:a()
local:1

In:i
Out:0

这是符合预期的,函数作用域内对 i 的赋值是本地的,不会影响外面的全局变量。之前在题目 26 中提到的 global 方案可以影响外面的全局变量,但是如果是嵌套的作用域呢:

In:x=0
...:defouter():
...:x=1
...:definner():
...:x=2
...:print("inner:",x)
...:
...:inner()
...:print("outer:",x)
...:
...:outer()
...:print("global:",x)
...:
inner:2
outer:1
global:0

使用global改造:

In:x=0
...:defouter():
...:x=1
...:definner():
...:globalx
...:x=2
...:print("inner:",x)
...:
...:inner()
...:print("outer:",x)
...:
...:outer()
...:print("global:",x)
...:
inner:2
outer:1
global:2

可以看到在最里面使用global,无论嵌套多少层,都会直接改最外面的那层x = 0。那么怎么影响到outer里面的x呢?这就是nonlocal的作用:

In[32]:x=0
...:defouter():
...:x=1
...:definner():
...:nonlocalx
...:x=2
...:print("inner:",x)
...:
...:inner()
...:print("outer:",x)
...:
...:outer()
...:print("global:",x)
...:
inner:2
outer:2
global:0

所谓nonlocal,其实就是说x不是函数 inner 的本地变量,那么就会向上影响到 outer。也就是影响 Enclosing (嵌套的父级函数的局部) 作用域。关于 Python 的 LEGB 作用域,可以深入搜索了解。

现在思考下,如果nonlocal的父级没有这个局部变量会继续向父级传播,但是注意,noncal声明的是函数内的局部变量,父级函数内没有此变量会报错:

In:x=0
...:defouter():
...:#x=1#注释了
...:definner():
...:nonlocalx
...:x=2
...:print("inner:",x)
...:
...:inner()
...:print("outer:",x)
...:
...:outer()
...:print("global:",x)
...:
InputIn[36]
nonlocalx
^
SyntaxError:nobindingfornonlocal'x'found

题目 30


这个题目考查对dataclasses模块的了解,它的问题在于类 A 的 c 已经定义的默认值,但是继承的 B 却没有。

我们看一下字典的同类问题就能了解:

In:d=dict(a,b=1,c)
InputIn[37]
d=dict(a,b=1,c)
^
SyntaxError:positionalargumentfollowskeywordargument

位置参数都要放在关键字参数之前,这个题目稍微有点防水。本来我是想出 Python 3.8 新增的参数类型的约束问题,既然想了就列出来大家感受下:

deff(a,b,/,c,d,*,e,f):
print(a,b,c,d,e,f)

#上述函数的合法调用项是:

A.f(10,20,30,d=40,e=50,f=60)
B.f(10,b=20,c=30,d=40,e=50,f=60)
C.f(a=10,b=20,c=30,d=40,e=50,f=60)
D.f(10,20,30,40,50,f=60)

答案是 A。Python 3.8 新增的语法/约束在/之前的参数必须在位置上指定并且不能用作关键字参数,*约束它之后的参数必须使用关键字参数而不能用位置参数。

为了优化 SEO,贴一下报错:

In:f(a=10,b=20,c=30,d=40,e=50,f=60)
---------------------------------------------------------------------------
TypeErrorTraceback(mostrecentcalllast)
InputIn[],in<cellline:1>()
---->1f(a=10,b=20,c=30,d=40,e=50,f=60)

TypeError:f()gotsomepositional-onlyargumentspassedaskeywordarguments:'a,b'

In:f(10,20,30,40,50,f=60)
---------------------------------------------------------------------------
TypeErrorTraceback(mostrecentcalllast)
InputIn[],in<cellline:1>()
---->1f(10,20,30,40,50,f=60)

TypeError:f()takes4positionalargumentsbut5positionalarguments(and1keyword-onlyargument)weregiven

延伸阅读

  1. https://peps.python.org/pep-0570/


又到了每年的开学季,最近图灵出版社有一大波图书折扣活动,电子书全场 6 折,非常实惠,机不可失,感兴趣的同学赶紧出手吧!


------分隔线----------------------------
相关学习资源
热门资讯
看了又看