[86题更新完毕] 牛客Python专项题

1. [str] 在Python3中,有关字符串的运算结果为:

strs = 'I like python and java'
one = strs.find('n')
print(one)
two = strs.rfind('n')
print(two)
  • 12,12
  • 15,15
  • 12,15
  • None,None

find是从前往后找,返回成功匹配的第一个字符的位置索引
rfind也是从前往后找,但是返回最后一次成功匹配的字符的位置索引

2. [open] 以下哪个代码是正确的读取一个文件?

  • f = open(“test.txt”, “read”)
  • f = open(“r”,“test.txt”)
  • f = open(“test.txt”, “r”)
  • f = open(“read”,“test.txt”)

Python中,打开文件语法为text = oepn(filePath, 操作方式,编码方式)
常见操作方式:

  • ‘r’:读
  • ‘w’:写
  • ‘a’:追加
    常见编码方式:
  • utf-8
  • gbk

3. [list] 在Python3中,对于以下程序正确的是:

lists = [1, 2, 3, 4, 5, 6]
print(lists[6:])
  • 报错
  • []
  • [1,2,3,4,5,6]
  • [6]

注意区分切片,切片一般指创造新的对象,而基于原列表而创造的切片一旦其切片值超出原列表索引下标则会无法从原列表中获取元素,因此返回一个空的下标
切片是浅拷贝,切片没有索引越界

4. python变量的查找顺序为()

  • 局部作用域>外部嵌套作用域>全局作用域>内置模块作用域
  • 外部嵌套作用域>局部作用域>全局作用域>内置模块作用域
  • 内置模块作用域>局部作用域>外部嵌套作用域>全局作用域
  • 内置模块作用域>外部嵌套作用域>局部作用域>全局作用域

Python变量的作用域遵循LEGB原则,即

  • L:Local,局部作用域,也就是我们在函数中定义的变量;
  • E:Enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
  • G:Globa,全局变量,就是模块级别定义的变量;
  • B:Built-in,系统内置模块里面的变量,比如int, bytearray等。

5. [作用域] 执行以下程序,结果输出为()

a = [1]
b = 2
c = 1


def fn(lis, obj):
    lis.append(b)
    obj = obj + 1
    return lis, obj


fn(a, c)
print(fn(a, c))

  • ([1, 2, 2], 2)
  • ([1, 2, 2], 3)
  • ([1, 2], 2)
  • ([1, 2], 3)

fn(a,c):调用了一次fn函数,这时候a变成了[1,2],c还是1,因为函数虽然返回了obj,但是没有赋值,出了函数之后c还是全局变量的那个c;
print(fn(a,c)):又调用了一次fn函数,过程同上,但是打印的时候打印的是函数的返回值,也就是此时的形参lis和obj的值,而此时lis是[1,2,2],而obj是2。

6. [逻辑运算符] python3中,执行 not 1 and 1的结果为

  • True
  • False
  • 0
  • 1

在Python3中,not 表示逻辑非,and 表示逻辑与,逻辑非(not)的运算优先级大于逻辑与(and)的优先级,则 not 1False,则 not 1 and 1 结果为 False
优先级not>and>or,谐音not at all
not 1 = False
False and 1 = False

7. [str] 在Python3中关于下列字符串程序运行结果为?

str1 = "exam is a example!" 
str2 = "exam" 
print(str1.find(str2, 7))
  • -1
  • 14
  • 0
  • 10

在Python3中 strs.find(str, beg=0, end=len(strs))表示在strs中返回第一次出现str的位置下标,beg表示在strs中的开始索引,默认为0(此题中为7),end结束索引,默认为strs的长度。但需要注意的是,返回的索引还是默认从0开始的,并不是beg的值(beg只是告诉程序是从该字符串第几个索引开始寻找),因此此题的结果为10

8. [str] 执行下列选项的程序,会抛出异常的是()

s1 = 'aabbcc'
s2 = 'abc'
count = s1.count(s2)

if count > 0 :
    print('s2是s1的子串')
else:
    print('s2不是s1的子串')

"""---------------------------"""

s1 = 'aabbcc'
s2 = 'abc'
index = s1.index(s2)

if index > -1:
    print('s2是s1的子串')
else:
    print('s2不是s1的子串')

"""---------------------------"""

s1 = 'aabbcc'
s2 = 'abc'
find = s1.find(s2)

if find != -1 :
    print('s2是s1的子串')
else:
    print('s2不是s1的子串')

"""---------------------------"""

s1 = 'aabbcc'
s2 = 'abc'
if s2 in s1:
    print('s2是s1的子串')
else:
    print('s2不是s1的子串')

正确答案为B。

  • count()函数没有匹配到对象返回0
  • index()函数没有匹配到对象报错value Error
  • find()函数没有匹配到对象返回-1
  • in 没有匹配到对象返回False

9. [Python 2] what gets printed? Assuming python version 2.x()

print type(1/2)
  • Python2 中除法默认向下取整,因此 1/2 = 0,为整型。
  • 而 Python3 中的除法为正常除法,会保留小数位,因此 1/2 = 0.5,为浮点型(float)。

10. [class] 有如下类定义,下列描述错误的是?

class A(object):
    pass

class B(A):
    pass

b = B()
  • isinstance(b, A) == True
  • isinstance(b, object) == True
  • issubclass(B, A) == True
  • issubclass(b, B) == True
  • isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()
  • issubclass() 函数用于判断参数是否是类型参数的子类。

11. [排序] 对列表 a = [1,2,3,1,2,4,6] 进行去重后,得到列表b,在不考虑列表元素的排列顺序的前提下,下列方法错误的是()

b = list(set(a))

"""---------------------------"""

b = {}
b = list(b.fromkeys(a))

"""---------------------------"""

a.sort()
b = []
i = 0

while i < len(a):
    if a[i] not in b:
        b.append(a[i])
    else:
        i += 1
        
"""---------------------------"""

a.sort()
for i in range(len(a)-1):
    if a[i] == a[i+1]:
        a.remove(a[i])
    else:
        continue
b = a        

D选项错误原因在于for循环的计数次数是不变的,但是随着a重复元素不断的移除,会导致列表出现IndexError。

12. [循环次数] 在Python3中,下列程序循环的次数为:

n = 1000
while n > 1:
    print(n)
    n = n / 2
  • 9
  • 10
  • 11
  • 无限循环

此题题意为:n 从1000开始循环,每次循环执行 n = n / 2,已知 29 = 512,210 = 1024,因此循环的次数为 10次,当循环10次后才会不满足循环条件

13. [set] 在Python3中,下列说法正确的是:

sets = {1, 2, 3, 4, 5}
print(sets[2])

程序运行结果为:

  • 2
  • 3
  • 报错
  • {3}

python3中,集合不能索引取值,因此会报错:TypeError: ‘set’ object is not subscriptable
集合无序,没有索引访问

14. [变量作用域] 执行以下代码,结果输出为()

num = 1
def fn():
	num += 1
	return lambda:print(num)

x = fn()
x()
  • 报错
  • 2
  • None
  • 1

虽然在函数外部声明num 为全局变量,但若函数体内对num变量重新赋值,其结果会使得函数内部屏蔽了外面的全局变量num,此时语句num += 1就会抛出异常,即num变量没有先赋值就直接引用了。

15. [字典的浅拷贝] 在python3中,对程序结果说明正确的是:

dicts = {'one': 1, 'two': 2, 'three': 3}
tmp = dicts.copy()
tmp['one'] = 'abc'
print(dicts)
print(tmp)
  • [‘one’: 1, ‘two’: 2, ‘three’: 3],[‘one’: ‘abc’, ‘two’: 2, ‘three’: 3]
  • {‘one’: 1, ‘two’: 2, ‘three’: 3},{‘one’: ‘abc’, ‘two’: 2, ‘three’: 3}
  • {‘one’: ‘abc’, ‘two’: 2, ‘three’: 3},{‘one’: ‘abc’, ‘two’: 2, ‘three’: 3}
  • {‘one’: 1, ‘two’: 2, ‘three’: 3},{‘one’: 1, ‘two’: 2, ‘three’: 3}

字典数据类型的copy函数,当简单的值替换的时候,原始字典和复制过来的字典之间互不影响,但是当添加,删除等修改操作的时候,两者之间会相互影响
所以新字典的值的替换对原字典没有影响

16. [str.find()] 在Python3中,下列程序返回的结果为:

strs = '123456'
print(strs.find('9'))
  • None
  • -1
  • 报错
  • findrfind 在查不到的时候-1
  • indexrindex 在查不到时都返回value error 所以编程时建议使用find

17. [编码顺序] 有一段python的编码程序如下,请问经过该编码的字符串的解码顺序是( )

urllib.quote(line.decode("gbk").encode("utf-16"))
  • gbk utf16 url解码
  • gbk url解码 utf16
  • url解码 gbk utf16
  • url解码 utf16 gbk

注意审题,问的是解码顺序不是编码顺序

18. [tuple赋值] 执行以下程序,输出结果为()

def fun(a=(), b=[]):
    a += (1, )
    b.append(1)
    return a, b


fun()
print(fun())
  • ((1,), [1, 1])
  • ((1,1), [1, 1])
  • ((1,), [1])
  • ((1,1), [1])

Python的默认参数只在函数定义时被赋值一次,而不会每次调用函数时又创建新的引用。这意味着,函数定义完成后,默认参数已经存在固定的内存地址了,如果使用一个可变的默认参数并对其进行改变,那么以后对该函数的调用都会改变这个可变对象,而默认参数如果是不可变对象,不存在该问题,因此正确答案为A选项。
注意审题,两次函数调用

19. [filter & map] 在Python3中,下列程序运行结果为:

strs = ['a', 'ab', 'abc', 'python']
y = filter(lambda s: len(s) > 2, strs)
tmp = list(map(lambda s: s.upper(), y))
print(tmp)
  • [‘ABC’, ‘PYTHON’]
  • [‘abc’, ‘PYTHON’]
  • [‘abc’, ‘python’]
  • [‘a’, ‘ab’]

filter中的条件是pass的条件
filter输出是一个filter对象,可以通过list, tuple等工厂函数转换为对应的数据类型

20. [tuple定义的方式] 下列哪种不是Python元组的定义方式?

  • (1)
  • (1, )
  • (1, 2)
  • (1, 2, (3, 4))

Python 中的 tuple 结构为 “不可变序列”,用小括号表示。为了区别数学中表示优先级的小括号,当 tuple 中只含一个元素时,需要在元素后加上逗号。

21. [dict取值] 在python3中,下列程序结果为:

dicts = {'one': 1, 'two': 2, 'three': 3}
print(dicts['one'])
print(dicts['four'])
  • 1,[]
  • 1,{}
  • 1,报错
  • 1,None

py3 访问不存在的索引或key:

  • 字典:
    • key访问报KeyError
    • get访问默认返回None
  • 列表、元组、字符串:IndexError

py3 切片越界(索引为自然数情况):

  • 列表:
    • start越界:返回[] 空列表
    • end越界:返回原列表浅拷贝
    • start、end均越界:[] 空列表
  • 元组:
    • start越界:返回() 空元组
    • end越界:返回原元组
    • start、end均越界:() 空元组
  • 字符串:
    • start越界:返回’’ 空字符
    • end越界:返回原字符串
    • start、end均越界:'' 空字符

22. [综合] 在python3.x执行下列选项的程序,不会抛出异常的是()

b = 1
def fn():
    nonlocal b
    b = b + 1
    print(b)
fn()

# ------------------------------------

tup = (('onion', 'apple'), ('tomato', 'pear'))
for _, fruit in tup:
    print(fruit)
    
# ------------------------------------

a = [b for b in range(10) if b % 2 == 0]
print(b)  # 

# ------------------------------------

lis = [1, 2, 'a', [1, 2]]
set(lis)
  • A选项,变量b属于全局变量,所以应该使用global声明而不是nonlocal;
  • B选项,可以使用_作为占位符,所以B选项不会报错;
  • C选项,python3.x中,使用列表生成式,中间变量b在生成列表后被销毁,因此再次使用变量b会报错;
  • D选项,集合元素不能是列表这类不可散列对象,因此会报错。

23. [return] 下面关于return说法正确的是( )

  • python函数中必须有return
  • return可以返回多个值
  • return没有返回值时,函数自动返回Null
  • 执行到return时,程序将停止函数内return后面的语句
  • A. 函数可以没有return
  • B. 看起来return可以返回多个值,但其实并不是,多个值返回是通过tuple实现的
  • C. 在Python中是没有Null这个数据类型的,返回的应该是None

24. [封闭函数] 执行下列程序,输出结果为()

def fn():
    t = []
    i = 0
    while i < 2:
        t.append(lambda x: print(i * x, end=","))
        i += 1
    return t


for f in fn():
    f(2)
  • 4,4,
  • 2,2,
  • 0,1,
  • 0,2,

函数fn存在闭包现象,自由变量是i,由于python闭包采用延迟绑定,也就是当调用匿名函数时,循环早已结束,此时i的值为2,所以输出结果都为2*2=4,正确答案为A。

25. [is & ==] a与b定义如下,下列哪个选项是正确的?

a = '123'
b = '123'
  • a != b
  • a is b
  • a == 123
  • a + b = 246

a,b为字符串不可变类型,所以指向相同地址,所以 a is b
+is指地址相同
==内容相同
===内容和格式相同
a+b=‘123123’
a==123,字符和int不相同

26. [strip & rstrip] 在Python3中,关于 strip() 和 rstrip() 的程序运行结果为:

strs = ' I like python '
one = strs.strip()
print(one)
two = strs.rstrip()
print(two)
  • ‘I like python’, ‘I like python’
  • ’ I like python’, ’ I like python’
  • ‘I like python’, ’ I like python’
  • ‘I like python’, 'I like python ’
  • split: 字符串首尾默认存在空白字符,所以当分隔符在字符串首尾的时候,有多少个分隔符就会产生多少个空格
  • strip():删除首尾空格;
  • rstrip():仅删除右空格;
strs = ' I like python '
one = strs.split(' ')
two = strs.strip()
print(one)  # ['', 'I', 'like', 'python', '']
print(two)  # I like python

strs = '        I like python '
one = strs.split(' ')
two = strs.strip()
print(one)  # ['', '', '', '', '', '', '', '', 'I', 'like', 'python']
print(two)  # I like python

27. [str.count] 在Python3中,关于字符数组的运行结果为:

names = ["Andrea", "Aaslay", "Steven", "Joa"]
lists = []
for name in names:
    if name.count('a') >= 2:
        lists.append(name)
print(lists)
  • [‘Andrea’, ‘Aaslay’, ‘Joa’]
  • []
  • [‘Andrea’, ‘Aaslay’]
  • [‘Aaslay’]

此题题意为:从名字的字符数组中找出名字中包含字母 ‘a’ 个数大于等于2个名字列表合集
首先对名字的字符数组进行遍历获取每一个名字,再通过 count() 函数判断名字中是否包含字母 ‘a’ 个数大于等于2个,将符合要求的名字字符存放到lists数组中(需要注意 ‘a’ 是区分大小写的),最后输出的 lists = [‘Aaslay’]

28. [key] 在Python3中,关于程序运行结果说法正确的是:

dicts = {}
dicts[([1, 2])] = 'abc'
print(dicts)
  • {([1,2]): ‘abc’}
  • {[1,2]: ‘abc’}
  • 报错
  • 其他说法都不正确

在Python3中,只有当元组内的所有元素都为不可变类型的时候,才能成为字典的key,因此程序运行过程中会报错:TypeError: unhashable type: ‘list’

29. [list.sort(key=, reverse=True)] 执行以下程序,输出结果为()

lis = ['apple', 'lemon', 'pear', 'peach']


def fn(x):
    return x[::-1]


lis.sort(key=fn, reverse=True)
print(lis)
  • [‘apple’, ‘lemon’, ‘peach’,‘pear’]
  • [‘pear’, ‘peach’, ‘lemon’, ‘apple’]
  • [‘apple’,‘pear’, ‘lemon’, ‘peach’]
  • [‘pear’, ‘lemon’, ‘peach’, ‘apple’]

函数fn的作用就是将字符反转,比如fn("apple") 得到 “elppa”。列表中元素按照fn函数规则,进行降序排列,此时的列表元素经过函数规则后:[‘elppa’,‘nomel’,‘raep’,hcaep],进行降序排列如下:[‘raep’, ‘nomel’, ‘hcaep’, ‘elppa’],但列表元素并不会改变,所以结果为D。

30. [_,__,__*__] 对于Python类中单下划线_foo、双下划线__foo与__foo__的成员,下列说法正确的是?

  • _foo 不能直接用于from module import *
  • __foo解析器用_classname__foo来代替这个名字,以区别和其他类相同的命名
  • __foo__代表python里特殊方法专用的标识
  • __foo 可以直接用于from module import *

python中主要存在四种命名方式:

  1. object:公用方法
  2. _object:半保护,被看作是“protect”,意思是只有类对象和子类对象能访问到这些变量,在模块或类外不可以使用,不能用from module import *导入。
    __object 是为了避免与子类的方法名称冲突, 对于该标识符描述的方法,父类的方法不能轻易地被子类的方法覆盖,他们的名字实际上是_classname__methodname
  3. __ object:全私有,全保护,私有成员“private”,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据,不能用from module import *导入。
  4. __ object__ :内建方法,用户不要这样定义

31. [import顺序] 当使用import导入模块时,按python查找模块的不同顺序可划分为以下几种:

①环境变量中的PYTHONPATH
②内建模块
③python安装路径
④当前路径,即执行Python脚本文件所在的路径

其中查找顺序正确的一组是()

  • ①④②③
  • ②①④③
  • ②④①③
  • ①②③④

python搜索模块的顺序为:内建模块>当前路径,即执行Python脚本文件所在的路径>环境变量中的PYTHONPATH>python安装路径,故答案为C。
内建模块(built-in) > 当前路径(./) > 环境变量 > Python安装路径

32. [id] 执行下列选项的程序,输出结果为True的是()

lis = [1,3,2]
a = id(lis)
lis = sorted(lis)
b = id(lis)
print(a==b)

print("======================")

lis = [1,3,2]
a = id(lis)
lis += [4,5]
b = id(lis)
print(a==b)

print("======================")

tup = (1,3,2)
a = id(tup)
tup += (4,5)
b = id(tup)
print(a==b)

print("======================")

tup = (1,3,2)
a = id(tup)
tup = sorted(tup)
b = id(tup)
print(a==b)

使用sorted()进行排序会生成新的序列,生成的新序列和原序列id值必然不同。对于可变对象,sorted()进行排序时原序列也发生变化,而本题A中用lis保存了生成的新序列,因此AD选项输出结果均为False;对于+=操作,如果是可变对象,则操作前后序列的id值不变,如果是不可变对象,则操作前后序列的id值改变,故B正确。

33. [split] 在Python3中,下列程序结果为:

strs = ' I like python '
one = strs.split(' ')
two = strs.strip()
print(one)
print(two)
  • [‘’, ‘I’, ‘like’, ‘python’, ‘’],'I like python ’
  • [‘I’, ‘like’, ‘python’],‘I like python’
  • [‘’, ‘I’, ‘like’, ‘python’, ‘’],‘I like python’
  • [‘I’, ‘like’, ‘python’],'I like python ’

当分割的地方有空格, 那么分割的时候就会保留空格。

34. [综合] 执行下列选项的程序,会抛出异常的是()

a = 1
b = 2
a,b = b,a

print("================")

a,*b,c = range(5)
print(a,b,c)

print("================")

lis = ['1','2']
a,b = list(map(int,lis))
print(a,b)

print("================")

tup = (1,(2,3))
a,b,c = tup
print(a,b,c)

ABCD四个选项的程序都是可迭代元素拆包问题。

  • A选项是两数交换的优雅写法;
  • B选项,python允许使用*来处理剩下的参数;
  • C选项是关于列表的拆包,让可迭代对象的元素一一赋值给对应的变量;
  • D选项会抛出异常,这是因为对应变量不满足元组的嵌套结构,正确的写法应该是a,(b,c) = tup

35. [非法赋值] 下列哪个语句在Python中是非法的?

  • x = y = z = 1
  • x = (y = z + 1)
  • x, y = y, x
  • x += y

36. [str.endwith] 下列代码输出为:

str = "Hello,Python";
suffix = "Python";
print (str.endswith(suffix,2));
  • True
  • False
  • 语法错误
  • P

str.endswith(suffix, start, end]) 用于判断字符串是否以指定后缀结尾,如果以指定后缀结尾返回True,否则返回False。
可选参数"start"与"end"为检索字符串的开始与结束位置。

37. [复数] 关于Python中的复数,下列说法错误的是()

  • 表示复数的语法是real + image j
  • 实部和虚部都是浮点数
  • 虚部必须后缀j,且必须小写
  • 方法conjugate返回复数的共轭复数
  1. 表示复数的语法是real + image j
  2. 实部和虚部都是浮点数
  3. 虚部的后缀可以是 “j” 或者 “J”
  4. 复数的 conjugate 方法可以返回该复数的共轭复数

38. [读取文件] Python调用( )函数可实现对文件内容的读取

  • read()
  • readline()
  • readlines()
  • readclose()

39. [print] What gets printed?()

print r"\nwoow"
  • new line then the string: woow
  • the text exactly like this: r"\nwoow"
  • the text like exactly like this: \nwoow
  • the letter r and then newline then the text: woow
  • the letter r then the text like this: nwoow

Python 中字符串的前导 r 代表原始字符串标识符,该字符串中的特殊符号不会被转义,适用于正则表达式中繁杂的特殊符号表示。例子如下:

print("\n This is a test paragraph")
print("\\n This is a test paragraph")
print(r"\\n This is a test paragraph")

"""
 This is a test paragraph
\n This is a test paragraph
\\n This is a test paragraph
"""

40. [join] 在Python3中,下列continue的用法:

res = []
for i in 'python':
    if i == 'h':
        continue
    res.append(i)
print(''.join(res))
  • ‘p’,‘y’,‘t’,‘h’,‘o’,‘n’
  • ‘p’,‘y’,‘t’,‘o’,‘n’
  • ‘python’
  • ‘pyton’

此题中的 continue 跳出本次循环,继续下一次循环,即为跳出 i == 'h' 时,因此 res = ['p','y','t','o','n'],最后打印的结果采用 join函数连接res中的字符,输出的结果为 'pyton'

41. [作用域] 执行以下代码,结果输出为()

num = 1

def fn():
    num += 1
    return lambda:print(num)

x = fn()
x()
  • 报错
  • 2
  • None
  • 1

虽然在函数外部声明num 为全局变量,但若函数体内对num变量重新赋值,其结果会使得函数内部屏蔽了外面的全局变量num,此时语句num += 1就会抛出异常,即num变量没有先赋值就直接引用了。

42. [list索引] 对于以下代码,描述正确的是:

list = ['1', '2', '3', '4', '5']
print list[10:]
  • 导致 IndexError
  • 输出[‘1’, ‘2’, ‘3’, ‘4’, ‘5’]
  • 编译错误
  • 输出[]

如果是索引访问,会导致IndexError,但本体考的是切片,切片操作时如果索引越界不会导致IndexError,只是返回一个空序列,这里返回空列表 []。

43. [str.title] 在Python3中。下列程序运行结果说明正确的是:

strs = 'abcd12efg'
print(strs.upper().title())
  • ‘ABCD12EFG’
  • ‘Abc12efg’
  • 语法错误
  • ‘Abcd12Efg’

str.title() 方法返回"标题化"的字符串,就是说所有单词的首个字母转化为大写,其余字母均为小写
注意,如果字符串是乱打的,那么中间的数字会将其进行分割。

strs = "This is a test paragraph."

print("1:", strs.upper())  # 所有字母大写
print("2:",strs.lower())  # 所有字母小写
print("3:",strs.title())  # 单词的首字母大写
print("4:",strs.capitalize())  # 字符串的首字母大写

print("-" * 30)

print("5:",strs.upper().title())
print("6:",strs.lower().title())

print("-" * 30)

print("7:",strs.upper().capitalize())
print("8:",strs.lower().capitalize())

"""
1: THIS IS A TEST PARAGRAPH.
2: this is a test paragraph.
3: This Is A Test Paragraph.
4: This is a test paragraph.
------------------------------
5: This Is A Test Paragraph.
6: This Is A Test Paragraph.
------------------------------
7: This is a test paragraph.
8: This is a test paragraph.
"""

44. [粗心] 若 a = range(100),以下哪些操作是合法的?

  • a[-3]
  • a[2:13]
  • a[::3]
  • a[2-3]

粗心了,D也是正确的。

45. [set] What gets printed?()

nums = set([1,2,2,3,3,3,4])
print len(nums)
  • 1
  • 2
  • 4
  • 5
  • 7

set中的数据不能重复,会自动去除重复的值

46. [dict.fromkeys] 在Python3中,程序运行结果为:

tmp = dict.fromkeys(['a', 'b'], 4)
print(tmp)
  • {(‘a’, ‘b’): 4}
  • {‘a’: 4}
  • {‘a’: 4, ‘b’: 4}
  • { ‘b’: 4}

Python3 dict.fromkeys(seq, value) 函数用于创建一个新字典,以序列 seq 中元素做字典的键,value 为字典所有键对应的初始值,该方法返回一个新字典。

47. [玄学] 假设可以不考虑计算机运行资源(如内存)的限制,以下 python3 代码的预期运行结果是:()

import math
def sieve(size):
    sieve= [True] * size
    sieve[0] = False
    sieve[1] = False
    for i in range(2, int(math.sqrt(size)) + 1):
        k= i * 2
        while k < size:
           sieve[k] = False
           k += i
    return sum(1 for x in sieve if x)
print(sieve(10000000000))
  • 455052510
  • 455052511
  • 455052512
  • 455052513

这道题,不能硬做,直接拿到python上跑,肯定会jj,要读懂代码的内涵。当然也可以先跑几个简单的例子,比如跑print(sieve(10))或者print(sieve(100))等等。其实,如果学过素数筛的就能很快看出,这是一道素数筛选的题。所以我们只要上网直接搜一下10000000000以内的素数个数就可以了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FA0Nbzn2-1658027312766)(./imgs_markdown/2022-07-14-14-43-34.png)]

48. [setter] 为了以下程序能够正常运行,①处可以填入的语句是()

class Animal:

    def __init__(self,color):

        self.__color = color

    @property
    def color(self):

        return self.__color

    @需要填写的修饰器名称
    def color(self,color):

        self.__color = color

animal = Animal('red')
print(animal.color)
animal.color = 'white'
print(animal.color)
  • property
  • setter
  • color.setter
  • setter.color

程序创建了一个animal对象,然后访问和修改对象的私有属性__color@property装饰器,相当于一个get方法,用于获取私有属性值,因此需要补充的是setter方法。
python对于setter装饰器的语法是:@方法名.setter,因此答案为C选项。

49. [玄学] 对于下面的python3函数,如果输入的参数n非常大,函数的返回值会趋近于以下哪一个值(选项中的值用Python表达式来表示)()

import random 
def foo(n):   
        random.seed()
     c1 = 0
     c2 = 0
     for i in range(n):
        x = random.random()
        y = random.random()
        r1 = x * x + y * y
        r2 = (1 - x) * (1 - x) + (1 - y) * (1 - y)
        if r1 <= 1 and r2 <= 1:
           c1 += 1
         else:
           c2 += 1
    return   c1 / c2
  • 4 / 3
  • (math.pi - 2) / (4 - math.pi)
  • math.e ** (6 / 21)
  • math.tan(53 / 180 * math.pi)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t896m7uk-1658027312767)(./imgs_markdown/2022-07-14-14-57-38.png)]

50. [dict] 在Python3中,下列程序运行结果为:

dicts = {}
dicts[(1, 2)] = ({3, (4, 5)})
print(dicts)
  • 报错
  • {(1, 2): {(4, 5), 3}}
  • {(1, 2): [(4, 5), 3]}
  • {(1, 2): [3, 4, 5]}

Python3中,对字典中添加键/值,题目中的字典键为 (1,2),对应的值为 ({3, (4, 5)})
需要注意的是:python中的set是以元素的哈希值确定位置

51. [list.pop()] 在Python中关于列表的运算结果为:

lists = [1, 2, 2, 3, 3, 3]
print(lists.count(3))
print(lists.pop())
lists.pop()
print(lists)
  • 2,3,[1, 2, 2, 3]
  • 3,3,[1, 2, 2, 3]
  • 3,3,[1, 2, 2, 3, 3]
  • 2,3,[1, 2, 2, 3, 3]

把list理解为是一个堆栈,堆栈遵循先进后出原则,所以pop()默认是从末尾弹出!

52. [str.find(str, start, end)] 在Python3中关于下列字符串程序运行结果为?

str1 = "exam is a example!" 
str2 = "exam" 
print(str1.find(str2, 7))
  • -1
  • 14
  • 0
  • 10

在Python3中 strs.find(str, beg=0, end=len(strs))表示在strs中返回第一次出现str的位置下标,beg表示在strs中的开始索引,默认为0(此题中为7),end结束索引,默认为strs的长度,因此此题的结果为10

53. [dict[取元素]] 在python3中,下列程序结果为:

dicts = {'one': 1, 'two': 2, 'three': 3}
print(dicts['one'])
print(dicts['four'])
  • 1,[]
  • 1,{}
  • 1,报错
  • 1,None

直接取元素的idx就会报错,而切片一般不会报错(返回一个空列表或空字典)

54. [pass] 在python3中关键字 pass 的使用,则:

for i in range(5):
    if i == 2:
        pass
    print(i)
  • 1,2,3,4,5
  • 0,1,2,3,4
  • 0,1,3,4
  • 0,1,2,3,4,5

别被迷惑

55. [综合题] 运行下列四个选项的程序,不会抛出异常的是()

"""-----------------------选项A-----------------------"""


class Rect:

    def __init__(self, width, height):
        self.width = width
        self.height = height

    @property
    def area(self):
        return self.height * self.width


rect = Rect(10, 20)
rect.area()  # TypeError: 'int' object is not callable
"""-----------------------选项B-----------------------"""
a = 0


def fun():
    a += 1
    print(a)


fun()  # UnboundLocalError: local variable 'a' referenced before assignment
"""-----------------------选项C-----------------------"""


class Animal:

    def __init__(self, color="白色"):
        Animal.color = color

    def get_color(self):
        print("Animal的颜色为", Animal.color)


class Cat(Animal):

    def __init__(self):
        pass


cat = Cat()
cat.get_color(
)  # AttributeError: type object 'Animal' has no attribute 'color'
"""-----------------------选项D-----------------------"""


class Cat:

    def __init__(self, color="白色"):
        self.__color = color


cat = Cat("绿色")
print(cat._Cat__color)  # 绿色
  • A选项,使用property会将方法转为属性,因此rect.area()应该改为rect.area
  • B选项,当给作用域中的一个变量赋值时,Python 会自动的把它当做是当前作用域的局部变量,从而会隐藏外部作用域中的同名变量,因此a += 1会报错
  • C选项,子类若有定义__init__()函数时,将不会自动继承父类的构造函数,因此在调用父类的get_color()函数时,会出现Animal找不到属性color,修改时只需在子类的__init__()函数中添加语句:super().__init__()
  • D选项,尽管color属性为私有属性,但是在类外部使用时,仍可以通过实例名._类名__xxx来访问
class Animal:

    def __init__(self, color="白色"):
        Animal.color = color

    def get_color(self):
        print("Animal的颜色为", Animal.color)


class Cat(Animal):

    def __init__(self):
        super().__init__()
    
# class Cat(Animal):
#     pass  # 这也可以运行的!


cat = Cat()
cat.get_color()  # AttributeError: type object 'Animal' has no attribute 'color'

56. [divmod] 在Python3中,程序运行结果为:

a = 100
b = 14
print(divmod(a, b))
  • (7, 0)
  • (7, 2)
  • [7, 2]
  • None

python3中,divmod将除法运算和取余运算结合在一起,结果返回一个tuple(元组)(商和余数)

57. [strip] 在Python3中。程序语句结果为:

strs = 'abbacabb'
print(strs.strip('ab'))
  • ‘ab’
  • 语法错误
  • ‘c’
  • ‘ca’

strs.strip('ab')中的'ab'表示的是一种集合,这里是指:[ab,ba,aa,bb,aaa,bbb,abb,baa]等;
strs两端,只要是包含了上述集合中的任何一个,都删除。


需要注意的是,strip删除的是第一个单词,看下面的例子就可以理解了:

str_1 = "abc bac cab bac acb cba"
print(f"|{str_1.strip('abc')}|")

str_2 = "abcbaccabbacacbcba"
print(f"|{str_2.strip('abc')}|")

print("-" * 30)
str_3 = "abc\nbac\ncab\nbac\nacb\ncba"  # \t会将string分割为不同的单词
print(f"|{str_3.strip('abc')}|")
print("-" * 30)

str_4 = "abc\tbac\tcab\tbac\tacb\tcba"  # \t也会将string分割为不同的单词
print(f"|{str_4.strip('abc')}|")
print("-" * 30)

str_5 = "abc,bac,cab,bac,acb,cba"  # ,也会将string分割为不同的单词
print(f"|{str_5.strip('abc')}|")

str_6 = "abc, bac, cab, bac, acb, cba"  # , 也会将string分割为不同的单词
print(f"|{str_6.strip('abc')}|")


str_7 = 'abbacabb'
print(f"|{str_7.strip('ab')}|")


"""
| bac cab bac acb |
||
------------------------------
|
bac
cab
bac
acb
|
------------------------------
|       bac     cab     bac     acb     |
------------------------------
|,bac,cab,bac,acb,|
|, bac, cab, bac, acb, |
|c|
"""

58. [私有属性继承] 根据以下程序,下列选项中,说法正确的是()

class Vector:
    __slots__='x','y'

    def __init__(self):
        pass


class Vector3d(Vector):
    __slots__='x','z'

    def __init__(self):
        pass


vector = Vector()
vector3d = Vector3d()
  • 若子类没有定义__slots__属性,则子类可以继承父类的__slots__属性
  • Vector类的实例对象vector会自动获得实例属性x和y
  • Vector3d类的实例对象vector3d最多只能允许属性x和z
  • Vector3d类的实例对象vector3d最多只能允许属性x、y和z
  1. python中凡是 “__” 开头的变量,都是私有变量,私有变量继承需要定义同名变量,因此A错误
  2. __slots__是python类中的特殊变量,用于限制实例对象的属性,如__slots__=‘x’,‘y’,那么实例对象的属性就只能从这些里面找,因此它起的是限制效果而非自动获得,因此B错误。
  3. 定义同名变量后子类继承父类的__slots__,从而支持xyz,因此C错
  4. 选D
class Vector:
    __slots__ = 'x', 'y'

    def __init__(self):
        pass


class Vector3d(Vector):  # 既然Vector3d已经继承Vector, 那么__slots__中就已经有x, y了
    __slots__ = 'x', 'z'  # 这句话的意思就是重新给Vector3d这个类定义了2个类属性,这里定义的x会覆盖从父类继承的x

    def __init__(self):
        pass


vector = Vector()
vector3d = Vector3d()

vector.x = 10
vector.y = 20
print(vector.x, vector.y)  # 10 20

# 我们再给它其他的属性
try:
    vector.z = 30
    print(vector.z)  # AttributeError: 'Vector' object has no attribute 'z'
except:
    pass

vector3d.x = 10
vector3d.y = 20
vector3d.z = 30
print(vector3d.x, vector3d.y, vector3d.z)  # 10 20 30

59. [Python2] Python2 中,以下不能在list中添加新元素的方法是()

  • append()
  • add()
  • extend()
  • insert()

60. [逻辑题] 下面这段程序的功能是什么?( )

def f(a, b):
    if b == 0:
        return a
    else:
        return f(b, a%b)
    
a, b = input(“Enter two natural numbers:)
print f(a, b)
  • 求AB最大公约数
  • 求AB最小公倍数
  • 求A%B
  • 求A/B

a % b 是求余数
辗转相除法,又称欧几里得算法,以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数。

61. [生成dict] 为输出一个字典dic = {‘a’:1,'b':2},下列选项中,做法错误的是()

lis1 = ['a','b'] 
lis2 = [1,2]
dic = dict(zip(lis1,lis2))
print(dic)


tup = ('a','b')
lis = [1,2]
dic = {tup:lis}
print(dic)


dic = dict(a=1,b=2)
print(dic)


lis = ['a','b']
dic = dict.fromkeys(lis)
dic['a'] = 1
dic['b'] = 2
print(dic)
A: {'a': 1, 'b': 2}
B: {('a', 'b'): [1, 2]}
C: {'a': 1, 'b': 2}
D: {'a': 1, 'b': 2}

62. [⭐️ 深拷贝、浅拷贝] 下面代码运行后,a、b、c、d四个变量的值,描述错误的是?

import copy
a = [1, 2, 3, 4, ['a', 'b']]
b = a
c = copy.copy(a)
d = copy.deepcopy(a)
a.append(5)
a[4].append('c')
  • a == [1,2, 3, 4, [‘a’, ‘b’, ‘c’], 5]
  • b == [1,2, 3, 4, [‘a’, ‘b’, ‘c’], 5]
  • c == [1,2, 3, 4, [‘a’, ‘b’, ‘c’]]
  • d == [1,2, 3, 4, [‘a’, ‘b’, ‘c’]]

首先我们看看a这个list在电脑里实际的存储情况:

[86题更新完毕] 牛客Python专项题_第1张图片

们再看看b的情况,b实际上和a指向的是同一个值,就好比人的大名和小名,只是叫法不同,但还是同一个人:

[86题更新完毕] 牛客Python专项题_第2张图片

接下来再看看c的情况,c的情况和a.copy()的情况是一样的,都是我们所谓的浅拷贝(浅复制),浅拷贝只会拷贝父对象,不会拷贝子对象,通俗的说就是只会拷贝到第二层

[86题更新完毕] 牛客Python专项题_第3张图片

若父对象发生变化,c不会变化,因为它已经复制的所有父对象,假如子对象发生变化则c会变,比如c[4]和a[4]实际都是一个变量list,他们都指向子对象,若子对象发生变化,他们必然都变化,比如变成[“a”,“d”],那它们指向的值也就变成了a、d。
再看看d的情况,这就是我们所说的深复制,不管a进行什么操作,都不会改变d了,他们已经指向不同的值(这里是指在内存中存储的位置不同了)。

[86题更新完毕] 牛客Python专项题_第4张图片

63. [深拷贝、浅拷贝] 在python3中,对程序结果说明正确的是:

dicts = {'one': 1, 'two': 2, 'three': 3}
tmp = dicts.copy()
tmp['one'] = 'abc'
print(dicts)
print(tmp)
  • [‘one’: 1, ‘two’: 2, ‘three’: 3],[‘one’: ‘abc’, ‘two’: 2, ‘three’: 3]
  • {‘one’: 1, ‘two’: 2, ‘three’: 3},{‘one’: ‘abc’, ‘two’: 2, ‘three’: 3}
  • {‘one’: ‘abc’, ‘two’: 2, ‘three’: 3},{‘one’: ‘abc’, ‘two’: 2, ‘three’: 3}
  • {‘one’: 1, ‘two’: 2, ‘three’: 3},{‘one’: 1, ‘two’: 2, ‘three’: 3}

字典数据类型的copy函数,当简单的值替换的时候,原始字典和复制过来的字典之间互不影响,但是当添加,删除等修改操作的时候,两者之间会相互影响。
所以新字典的值的替换对原字典没有影响

64. [str.count] 在Python3中,关于字符数组的运行结果为:

names = ["Andrea", "Aaslay", "Steven", "Joa"]
lists = []
for name in names:
    if name.count('a') >= 2:
        lists.append(name)
print(lists)
  • [‘Andrea’, ‘Aaslay’, ‘Joa’]
  • []
  • [‘Andrea’, ‘Aaslay’]
  • [‘Aaslay’]

Python严格区分大小写,所以答案选D不选C

65. [小整数对象池] 已知a = [1, 2, 3]b = [1, 2, 4],那么id(a[1])==id(b[1])的执行结果 ()

  • True
  • False

id(object)是python的一个函数用于返回object的内存地址。但值得注意的是,python 为了提高内存利用效率会对一些简单的对象(如数值较小的int型对象,字符串等)采用重用对象内存的办法。
python中对于小整数对象有一个小整数对象池,范围在[-5,257)之间。对于在这个范围内的征数,不会新建对象,直接从小整数对象池中取就行。
在python3.6中对于小整数对象有一个小整数对象池,范围不止在[-5,257)之间。我试了百万以上的数地址都是相同的(在解释器中是,在开发工具中不是)

66. [子类是否可以影响父类] 执行以下程序,输出结果为()

class Base(object):
    count = 0
    def __init__(self):
        pass


b1 = Base()
b2 = Base()

b1.count = b1.count + 1
print(b1.count,end=" ")
print(Base.count,end=" ")
print(b2.count)
  • 1 1 1
  • 1 0 0
  • 1 0 1
  • 抛出异常

count为类属性,类属性可以为实例属性提供默认值,也就是,当使用b1.count时,count成了b1对象的实例属性,实例属性不会影响到类属性的值,也不会影响到其他实例属性,所以对b1.count进行修改时只会影响自身,Base.count和b2.count的值仍为0。
count是类变量

  • 通过类名修改类变量,会作用到所有的实例化对象
  • 通过类对象是无法修改类变量的。通过类对象对类变量赋值,其本质将不再是修改类变量的值,而是在给该对象定义新的实例变量

67. [getitem] 根据以下程序,下列选项中,说法正确的是()

class Foo():
    def __init__(self):
        pass

    def __getitem__(self,pos):
        return range(0,30,10)[pos]


foo = Foo()
  • foo对象表现得像个序列
  • 可以使用len(foo)来查看对象foo的元素个数
  • 可以使用for i in foo:print(i)来遍历foo的元素
  • 不能使用foo[0]来访问对象foo的第一个元素
  • 若要表现像个序列,必须满足序列的两个方法:①__len__和②__getitem__,由于Foo类中没有实现__len__,因此不满足序列协议,foo对象不像序列,A错误;
  • foo对象没有定义__len__方法,不能使用它来查看对象个数,B错误;
    对对象的迭代需要调用__iter__,如果没有定义该方法,python会调用__getitem__(),让迭代和in运算符可用,因此foo是可迭代的,C正确;
    根据索引访问对象元素,会调用__getitem__(),因此D错误。
foo = Foo()

print(f"foo对象: {foo}")  # <__main__.Foo object at 0x0000022E78DA4BE0>

try:
    print(f"len(foo): {len(foo)}")
except:
    print("不可以通过len(foo)查看对象foo的元素个数")  # 不可以通过len(foo)查看对象foo的元素个数
    
for i in foo:  # 0 \n 10 \n 20
    print(i)

print(f"foo[0]: {foo[0]}")  # foo[0]: 0

68. [Python标识符] 下面哪个不是合法的Python标识符?

  • int32
  • 40XL
  • self
  • name

python中的标识符:

  1. 第一个字符必须是字母表中字母或下划线_
  2. 标识符的其他的部分由字母、数字和下划线组成。
  3. 标识符对大小写敏感。
  4. 不可以是python中的关键字,如False、True、None、class等。
    注意:self不是python中的关键字。类中参数self也可以用其他名称命名,但是为了规范和便于读者理解,推荐使用self。

69. [Python join] 在Python3中,下列程序运行结果为:

print('\n'.join(['a', 'b', 'c']))
  • ‘abc’
  • a \n b \n c
  • 报错
  • None

Python中join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
join()方法语法:str.join(sequence)

print('\n'.join(['a', 'b', 'c']))

print("-----------------")

print('-'.join(["a", "b", "c"]))


"""
a
b
c
-----------------
a-b-c
"""

70. [join] 在Python3中,下列continue的用法:

res = []
for i in 'python':
    if i == 'h':
        continue
    res.append(i)
print(''.join(res))
  • ‘p’,‘y’,‘t’,‘h’,‘o’,‘n’
  • ‘p’,‘y’,‘t’,‘o’,‘n’
  • ‘python’
  • ‘pyton’

此题中的 continue 跳出本次循环,继续下一次循环,即为跳出 i == 'h' 时,
因此res = ['p','y','t','o','n'],最后打印的结果采用 join 函数连接res中的字符,输出的结果为 ‘pyton’
直接print(res)是不带''的,因此加了join后就会带''

res = []
for i in 'python':
    if i == 'h':
        continue
    res.append(i)


print(res)  # ['p', 'y', 't', 'o', 'n']
[print(i, end=" ") for i in res]  # p y t o n
print("")  # \n
print(''.join(res))  # pyton -> 其实就是不用任何东西连接
print('-'.join(res))  # p-y-t-o-n

71. [global] What gets printed?()

counter = 1 
def doLotsOfStuff(): 
    global counter
    for i in (1, 2, 3): 
        counter += 1 
doLotsOfStuff()
print counter
  • 1
  • 3
  • 4
  • 7
  • none of the above

最后要注意第 5 行的坑,是 counter += 1 而不是 counter += i ,因此答案是 4 而不是 7,选答案 C。

72. [思想] 在Python3中,下列程序循环的次数为:

n = 1000
while n > 1:
    print(n)
    n = n / 2
  • 9
  • 10
  • 11
  • 无限循环

此题题意为:n 从1000开始循环,每次循环执行 n = n / 2,已知 2^9 = 512,2^10 = 1024,因此循环的次数为 10次,当循环10次后才会不满足循环条件

73. [总错] 当使用import导入模块时,按python查找模块的不同顺序可划分为以下几种:

  1. 环境变量中的PYTHONPATH
  2. 内建模块
  3. python安装路径
  4. 当前路径,即执行Python脚本文件所在的路径

其中查找顺序正确的一组是()

  • ①④②③
  • ②①④③
  • ②④①③
  • ①②③④

记住,别再错了

74. [Python对象池] 执行下列选项中的程序,输出结果为False的是()

t1 = (1,2,3)
t2 = t1[:]
print(t1 is t2)
lis1 = [1,2,3]
lis2 = lis1[:]
print(id(lis1)==id(lis2))
s1 = '123'
s2 = '123'
print(s1 is s2)
a = 123
b = 123
print(id(a) == id(b))
  • ①数字②字符③下划线组成的短字符串以及④[-5,256]内的整数存在内存驻留,将其赋值给多个不同的对象时,内存中只有一个副本,多个对象共享该副本,故CD选项结果均为True;
  • 对于A选项,元组的[:]并不会创建副本,而是返回同一个对象的引用,所以t1和t2的id值均一样,结果为True;
  • 对于B选项,列表的[:]会创建副本,其id值发生改变,结果为False。

75. [+=] 执行以下程序,输出结果为()

def fun(a=(), b=[]):
    a += (1,)
    b.append(1)
    return a, b


fun()
print(fun())
  • ((1,), [1, 1])
  • ((1,1), [1, 1])
  • ((1,), [1])
  • ((1,1), [1])

Python的默认参数只在函数定义时被赋值一次,而不会每次调用函数时又创建新的引用。这意味着,函数定义完成后,默认参数已经存在固定的内存地址了,如果使用一个可变的默认参数并对其进行改变,那么以后对该函数的调用都会改变这个可变对象,而默认参数如果是不可变对象,不存在该问题,因此正确答案为A选项。

a = ()
a += (1,)
print(f"a: {a}")  # a: (1,)

b = ()
b += (1, 2, 3, 4, 5, 6)
print(f"b: {b}")  # b: (1, 2, 3, 4, 5, 6)

c = []
c += [1,]
print(f"c: {c}")  # c: [1]

d = []
d += [1, 2, 3, 4, 5, 6, 7]
print(f"d: {d}")  # d: [1, 2, 3, 4, 5, 6, 7]

76. [range对象] 若 a = range(100),以下哪些操作是合法的?

  • a[-3]
  • a[2:13]
  • a[::3]
  • a[2-3]
a = range(100)

print(a)  # range(0, 100)
print(a[10])  # 10
print(a[:])  # range(0, 100)
print(a[1:2])  # range(1, 2)
print(a[-3])  # 97

77. [filter] 以下代码运行结果为:

func = lambda x:x%2
result = filter(func, [1, 2, 3, 4, 5])
print(list(result))
  • [1,3,5]
  • [1,2,1,0,1]
  • [1, 2, 3, 4, 5]
  • [1,2,3]

filter(function, iterable), filter函数是python中的高阶函数, 第一个参数是一个筛选函数, 第二个参数是一个可迭代对象, 返回的是一个生成器类型, 可以通过next获取值. 这里大致讲述下原理, filter()把传入的function依次作用于iterable的每个元素, 满足条件的返回true, 不满足条件的返回false, 通过true还是false决定将该元素丢弃还是保留.
所以对2和4取余为0舍弃1.3.5取余为1为真保留;

通过下面的例子我们可以看到filter函数会保留什么样的数值:

func = lambda x: x
result = filter(func, [True, False, -3, -2, -1, 0, 1, 2, 3, 4, 5])
print(list(result))  # [True, -3, -2, -1, 1, 2, 3, 4, 5]

可以看到,filter函数不保留的有:

  1. False
  2. 0

其他的都会保留

78. [列表的子列表] 执行以下程序,输出结果为()

a = [['1','2'] for i in range(2)]
b = [['1','2']]*2

a[0][1] = '3'
b[0][0] = '4'
print(a,b) 
  • [[‘1’, ‘3’], [‘1’, ‘3’]] [[‘4’, ‘2’], [‘4’, ‘2’]]
  • [[‘1’, ‘3’], [‘1’, ‘2’]] [[‘4’, ‘2’], [‘4’, ‘2’]]
  • [[‘1’, ‘3’], [‘1’, ‘2’]] [[‘4’, ‘2’], [‘1’, ‘2’]]
  • [[‘1’, ‘3’], [‘1’, ‘3’]] [[‘4’, ‘2’], [‘1’, ‘2’]]

在python中, 如果用一个列表a乘一个数字会得到一个新的列表b, 这个新的列表b的元素是a的元素重复n次(可以理解*是浅拷贝)。

79. [tuple] 执行以下程序,下列选项中,说法正确的是()

tup = (1,2,[3,4])  # ①
tup[2]+=[5,6]  # ②
  • 执行代码②后,变量tup[2]的id发生改变
  • ①和②均可以执行而不会抛出异常
  • 执行代码②时会抛出异常,最终tup的值为(1,2,[3,4,5,6])
  • 执行代码②时会抛出异常,最终tup的值为(1,2,[3,4])
  • tup[2]是列表,列表是可变对象,对于可变对象,执行+=后并不会改变其id值,A错误;
  • 执行②时会抛出异常,“+=”的执行顺序是先对[3,4]执行+操作,其结果为[3,4,5,6],然后再执行”=“,此时会抛出异常,这是因为元组不允许元素的引用被重新赋值,尽管赋值后列表的id是不变的,若改成tup[2].extend([5,6])就不会抛出异常。

80. [总错] 在python3中,对程序结果说明正确的是:

dicts = {'one': 1, 'two': 2, 'three': 3}
tmp = dicts.copy()
tmp['one'] = 'abc'
print(dicts)
print(tmp)
  • [‘one’: 1, ‘two’: 2, ‘three’: 3],[‘one’: ‘abc’, ‘two’: 2, ‘three’: 3]
  • {‘one’: 1, ‘two’: 2, ‘three’: 3},{‘one’: ‘abc’, ‘two’: 2, ‘three’: 3}
  • {‘one’: ‘abc’, ‘two’: 2, ‘three’: 3},{‘one’: ‘abc’, ‘two’: 2, ‘three’: 3}
  • {‘one’: 1, ‘two’: 2, ‘three’: 3},{‘one’: 1, ‘two’: 2, ‘three’: 3}

对于字典、列表、集合来说,浅拷贝只拷贝对应的内存地址,而深拷贝会完全复制拷贝一份新的。对于字符串、数字这些,浅拷贝跟深拷贝都是一样拷贝一份新的
old_dicts = {'name': tom, 'age': 18, 'like': [1,2,3]}

  • 浅拷贝 new_dicts = old_dicts.copy() 修改 name 或者 age 时,不会相互影响,而修改like时,会互相影响。
  • 深拷贝 new_deep_dicts = old_dicts.deepcopy() 就是完完全全复制了一份新的,从头复制到尾,是相互独立的两个字典了,不管怎么修改都不会影响到对方

81. [正则表达式] 下列程序打印结果为()

import re 
str1 = "Python's features" 
str2 = re.match( r'(.*)on(.*?) .*', str1, re.M|re.I)
print str2.group(1)
  • Python
  • Pyth
  • thon’s
  • Python‘s features

re模块实现正则的功能:

re.match(正则表达式, 要匹配的字符串, [匹配模式])
  • 题中要匹配的字符串为str1 = "Python's features"
  • 正则表达式r'(.*)on(.*?) .*'
    • r表示后面的字符串是一个普通字符串(比如\n会译为\n,而不是换行符)
    • ()符号包住的数据为要提取的数据,通常与.group()函数连用。

正则表达式的规则:

  • .匹配单个任意字符
  • *匹配前一个字符出现0次或无限次
  • ?匹配前一个字符出现0次或1次
  • (.*)提取的数据为str1字符串中on左边的所有字符,即Pyth
  • (.*?)提取的数据为str1中on右边,空格前面,即's
  • .group(0)输出的是匹配正则表达式整体结果
    • .group(1)列出第一个括号匹配部分
    • .group(2)列出第二个括号匹配部分

82. [class@property] 根据以下代码,下列选项中,说法正确的是()

class Rectangle:
    __count = 0

    def __init__(self,width,height):
        Rectangle.__count += 1
        self.__width = width
        self.__height = height

    @property
    def area(self):
        return self.__height * self.__width

rectangle = Rectangle(200,100)
  • 创建实例对象rectangle后,可在类外使用rectangle.area()来访问area属性
  • area属性为对象的非私有属性,可以访问和修改
  • 变量__count的作用是为了统计创建对象的个数
  • 因为__width__height为私有变量,所以在类外不可能访问__width__height属性
  • 使用@property将方法转为属性,该属性为只读属性,只可访问但是不可以修改,使用对象.方法名来访问该属性,但是方法不能再加小括号,故AB选项说法均错误;
  • 变量__count是类的私有变量,由于每次创建对象时,其值自增1,所以可以用来统计创建对象的个数,C正确;
  • 虽然__height__width为私有变量,不能在类外直接使用对象名.属性名来访问,但是,仍可以使用rectangle._Rectangle__widthrectangle._Rectangle__height来强制访问,故D错误。

83. [set取索引] 在Python3中,下列说法正确的是:

sets = {1, 2, 3, 4, 5}
print(sets[2])
  • 2
  • 3
  • 报错
  • {3}

python3中,集合不能索引取值,因此会报错:TypeError: 'set' object is not subscriptable
集合无序,没有索引访问

84. [str.replace] 在Python3中,字符串的变换结果为:

strs = 'I like python and java'
print(strs.replace('I', 'Your'))
print(strs.replace('a', '*', 2))
  • ‘Your like python and java’,‘I like python nd jv*’
  • ‘I like python and java’,‘I like python nd jv*’
  • ‘Your like python and java’,‘I like python nd jva’
  • ‘I like python and java’,‘I like python nd jva’

str.replace(old, new, count=-1)是用来替换字符/字符串的,count是替换的最大次数,如果不指定默认为-1,表示替换所有。

85. [双重列表推导式] 执行以下程序,输出结果为()

sizes = ['S','M']
colors = ['white','black']

shirts = [(size,color) for color in colors for size in sizes]
print(shirts)
  • [(‘S’, ‘white’), (‘S’, ‘black’), (‘M’, ‘white’), (‘M’, ‘black’)]
  • [(‘S’, ‘white’), (‘M’, ‘white’), (‘S’, ‘black’), (‘M’, ‘black’)]
  • [(‘S’, ‘white’), (‘M’, ‘black’)]
  • [(‘white’, ‘S’), (‘black’, ‘M’)]

列表推导式中在最左边的是最外层循环,越往右循环越靠内

sizes = ['S','M']
colors = ['white','black']

shirts = [(size,color) for color in colors for size in sizes]  # for循环是从左到右的
print(shirts)

shirts = []
for color in colors:
    for size in sizes:
        shirts.append((size, color))
        
print(shirts)

86. [new__和__init] 对于python中__new__和__init__的区别,下列说法正确的是?

  • __new__是一个静态方法,而__init__是一个实例方法
  • __new__方法会返回一个创建的实例,而__init__什么都不返回
  • 只有在__new__返回一个cls的实例时,后面的__init__才能被调用
  • 当创建一个新实例时调用__new__,初始化一个实例时用__init__

根据官方文档:

  • __init__是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值。
  • __new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例,是个静态方法。
    即,__new__在__init__之前被调用,__new__的返回值(实例)将传递给__init__方法的第一个参数,然后__init__给这个实例设置一些参数。
  1. __init__ 方法为初始化方法, __new__方法才是真正的构造函数。
  2. __new__方法默认返回实例对象供__init__方法、实例方法使用。
  3. __init__ 方法为初始化方法,为类的实例提供一些属性或完成一些动作。
  4. __new__ 方法创建实例对象供__init__ 方法使用,__init__方法定制实例对象。
  5. __new__是一个静态方法,而__init__是一个实例方法。

__new__是真正的构造方法,所以它是属于cls自身的,因此是一个静态方法;而__init__方法是针对生成的不同的类对象,所以是实例方法。

你可能感兴趣的:(面试题(Interview,Questions),Python,python)