8个Python面试必考的题目,小编也被坑过 ToT

写在前面

小编学习Python已经三年多了,现在稳定在一家公司快一年了,回想起来一年以前的面试经历真的有点胆战心惊啊!

因为面试题目一不小心就会被坑啊~

你经历过绝望么?

当你被Python面试题目坑到的时候内心真的一万个草泥马徘徊在心中啊o(╥﹏╥)o

下面小编就分享一些小编亲身经历过的一些Python神坑面试题哦~

干货来了

1、下面这段代码的输出结果是什么?请解释。

def extendList(val, list=[]):
 list.append(val)
 return list
list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList(‘a‘)
print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

如何修改extendList的定义能够产生以下预期的行为?

上面代码输出结果将是:

list1 = [10, ‘a‘]
list2 = [123]
list3 = [10, ‘a‘]

讲解:

很多人都会误认为list1=[10],list3=[‘a’],因为他们以为每次extendList被调用时,列表参数的默认值都将被设置为[].但实际上的情况是,新的默认列表只在函数被定义的那一刻创建一次。

当extendList被没有指定特定参数list调用时,这组list的值随后将被使用。这是因为带有默认参数的表达式在函数被定义的时候被计算,不是在调用的时候被计算。因此list1和list3是在同一个默认列表上进行操作(计算)的。而list2是在一个分离的列表上进行操作(计算)的。(通过传递一个自有的空列表作为列表参数的数值)。

extendList的定义可以作如下修改。

尽管,创建一个新的列表,没有特定的列表参数。

下面这段代码可能能够产生想要的结果。

def extendList(val, list=None):
 if list is None:
 list = []
 list.append(val)
 return list

通过上面的修改,输出结果将变成:

list1 = [10]
list2 = [123]
list3 = [‘a‘]

2、下面这段代码的输出结果将是什么?请解释。

def multipliers():
 return [lambda x : i * x for i in range(4)]
print [m(2) for m in multipliers()]

讲解:

你如何修改上面的multipliers的定义产生想要的结果?

上面代码输出的结果是[6, 6, 6, 6] (不是我们想的[0, 2, 4, 6])。

上述问题产生的原因是Python闭包的延迟绑定。这意味着内部函数被调用时,参数的值在闭包内进行查找。因此,当任何由multipliers()返回的函数被调用时,i的值将在附近的范围进行查找。那时,不管返回的函数是否被调用,for循环已经完成,i被赋予了最终的值3。

因此,每次返回的函数乘以传递过来的值3,因为上段代码传过来的值是2,它们最终返回的都是6(3*2)。碰巧的是,《The Hitchhiker’s Guide to Python》也指出,在与lambdas函数相关也有一个被广泛被误解的知识点,不过跟这个case不一样。由lambda表达式创造的函数没有什么特殊的地方,它其实是和def创造的函数式一样的。

下面是解决这一问题的一些方法。

一种解决方法就是用Python生成器。

def multipliers():
 for i in range(4): yield lambda x : i * x

另外一个解决方案就是创造一个闭包,利用默认函数立即绑定。

def multipliers():
 return [lambda x, i=i : i * x for i in range(4)]

还有种替代的方案是,使用偏函数:

from functools import partial
from operator import mul
def multipliers():
 return [partial(mul, i) for i in range(4)]

3、下面这段代码的输出结果将是什么?请解释。

class Parent(object):
 x = 1
class Child1(Parent):
 pass
class Child2(Parent):
 pass
print Parent.x, Child1.x, Child2.x
Child1.x = 2
print Parent.x, Child1.x, Child2.x
Parent.x = 3
print Parent.x, Child1.x, Child2.x

输出结果将是:

1 1 1
1 2 1
3 2 3

讲解:

让很多人困惑或惊讶的是最后一行输出为什么是3 2 3 而不是 3 2 1.为什么在改变parent.x的同时也改变了child2.x的值?但与此同时没有改变Child1.x的值?

此答案的关键是,在Python中,类变量在内部是以字典的形式进行传递。

如果一个变量名没有在当前类下的字典中发现。则在更高级的类(如它的父类)中尽心搜索直到引用的变量名被找到。(如果引用变量名在自身类和更高级类中没有找到,将会引发一个属性错误。)

因此,在父类中设定x = 1,让变量x类(带有值1)能够在其类和其子类中被引用到。这就是为什么第一个打印语句输出结果是1 1 1

因此,如果它的任何一个子类被覆写了值(例如说,当我们执行语句Child1.x = 2),这个值只在子类中进行了修改。这就是为什么第二个打印语句输出结果是1 2 1

最终,如果这个值在父类中进行了修改,(例如说,当我们执行语句Parent.x = 3),这个改变将会影响那些还没有覆写子类的值(在这个例子中就是Child2)这就是为什么第三打印语句输出结果是3 2 3

4、下面这段代码在Python2下输出结果将是什么?请解释。

def div1(x,y):
 print "%s/%s = %s" % (x, y, x/y)
def div2(x,y):
 print "%s//%s = %s" % (x, y, x//y)
div1(5,2)
div1(5.,2)
div2(5,2)
div2(5.,2.)

讲解:

在Python3下结果会有怎样的不同?(当然,假设上述打印语句被转换成Python3的语法)

在Python2中,上述代码输出将是

5/2 = 2
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0

默认情况下,Python 2 自动执行整形计算如果两者都是整数。因此,5/2 结果是2,而5./2结果是2.5

注意,在Python2中,你可以通过增加以下引用来覆写这个行为。

from future import division

同时要注意的是,//操作符将总是执行整形除法,不管操作符的类型。这就是为什么即使在Python 2中5.0//2.0的结果是2.0。然而在Python3中,没有此类特性,

例如,在两端都是整形的情况下,它不会执行整形除法

因此,在Python3中,将会是如下结果:

5/2 = 2.5
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0

注: 在 Python 3 中,/ 操作符是做浮点除法,而 // 是做整除(即商没有余数,比如 10 // 3 其结果就为 3,余数会被截除掉,而 (-7) // 3 的结果却是 -3。这个算法与其它很多编程语言不一样,需要注意,它们的整除运算会向0的方向取值。而在 Python 2 中,/ 就是整除,即和 Python 3 中的 // 操作符一样)

5、下面代码的输出结果将是什么?

list = [‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘]
print list[10:]

讲解:

下面的代码将输出[],不会产生IndexError错误。就像所期望的那样,尝试用超出成员的个数的index来获取某个列表的成员。

例如,尝试获取list[10]和之后的成员,会导致IndexError.

然而,尝试获取列表的切片,开始的index超过了成员个数不会产生IndexError,而是仅仅返回一个空列表。

这成为特别让人恶心的疑难杂症,因为运行的时候没有错误产生,导致bug很难被追踪到。

6、考虑下列代码片段:

list = [ [ ] ] * 5
list # output?
list[0].append(10)
list # output?
list[1].append(20)
list # output?
list.append(30)
list # output?

2,4,6,8行将输出什么结果?试解释。

输出的结果如下:

[[], [], [], [], []]
[[10], [10], [10], [10], [10]]
[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20]]
[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30]

讲解:

第一行的输出结果直觉上很容易理解,例如 list = [ [ ] ] * 5 就是简单的创造了5个空列表。然而,理解表达式list=[ [ ] ] * 5的关键一点是它不是创造一个包含五个独立列表的列表,而是它是一个创建了包含对同一个列表五次引用的列表。只有了解了这一点,我们才能更好的理解接下来的输出结果。

list[0].append(10) 将10附加在第一个列表上。

但由于所有5个列表是引用的同一个列表,所以这个结果将是:

[[10], [10], [10], [10], [10]]

同理,list[1].append(20)将20附加在第二个列表上。但同样由于5个列表是引用的同一个列表,所以输出结果现在是:

[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20]]

作为对比, list.append(30)是将整个新的元素附加在外列表上,因此产生的结果是: [[10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30].

7、Given a list of N numbers。

给定一个含有N个数字的列表。

使用单一的列表生成式来产生一个新的列表,该列表只包含满足以下条件的值:

(a)偶数值

(b)元素为原始列表中偶数切片。

例如,如果list[2]包含的值是偶数。那么这个值应该被包含在新的列表当中。因为这个数字同时在原始列表的偶数序列(2为偶数)上。然而,如果list[3]包含一个偶数,

那个数字不应该被包含在新的列表当中,因为它在原始列表的奇数序列上。

讲解:

对此问题的简单解决方法如下:

[x for x in list[::2] if x%2 == 0]

例如,给定列表如下:

list = [ 1 , 3 , 5 , 8 , 10 , 13 , 18 , 36 , 78 ]

列表生成式[x for x in list[::2] if x%2 == 0] 的结果是,

[10, 18, 78]

这个表达式工作的步骤是,第一步取出偶数切片的数字,

第二步剔除其中所有奇数。

8、给定以下字典的子类,下面的代码能够运行么?为什么?

class DefaultDict(dict):
 def __missing__(self, key):
 return []

d = DefaultDict()
d[‘florp‘] = 127

能够运行

讲解:

当key缺失时,执行DefaultDict类,字典的实例将自动实例化这个数列。

写在最后

希望小编的总结能够对于正在面试Python相关行业的你有所帮助!

最后祝大家面试少遇坑,都能找到自己心仪的工资!!!

原文地址:https://www.cnblogs.com/l520/p/10255290.html

时间: 2024-11-05 11:23:06

8个Python面试必考的题目,小编也被坑过 ToT的相关文章

Java BAT大型公司面试必考技能视频-1.HashMap源码分析与实现

视频通过以下四个方面介绍了HASHMAP的内容 一. 什么是HashMap Hash散列将一个任意的长度通过某种算法(Hash函数算法)转换成一个固定的值. MAP:地图 x,y 存储 总结:通过HASH出来的值,然后通过值定位到这个MAP,然后value存储到这个MAP中的HASHMAP基本原理 1. KEY 是否可以为空?可以,Null当成一个Key来存储 2. 如果Hash KEY重复了会覆盖吗?会覆盖,但返回旧的值 3. HASHMAP什么时候做扩容?put 的时候,阀值高于或等于0.7

95%的技术面试必考的JVM知识点都在这,另附加分思路!

概述:知识点汇总 jvm的知识点汇总共6个大方向:内存模型.类加载机制.GC垃圾回收是比较重点的内容.性能调优部分偏重实际应用,重点突出实践能力.编译器优化和执行模式部分偏重理论基础,主要掌握知识点. 各个部分的内容如下: 1>内存模型部分:程序计数器.方法区.堆.栈.本地方法栈的作用,保存哪些数据: 2>类加载部分:双亲委派的加载机制以及常用类加载器分别加载哪种类型的类: 3>GC部分:分代回收的思想和依据,以及不同垃圾回收算法实现的思路.适合的场景: 4>性能调优部分:常用的j

2018年 Python面试必看的10个问题及答案

最近开始整理python的资料,博主建立了一个qq群,希望给大家提供一个交流的同平台 938587844 . 找工作是每个学习Python人员的目标,为了更好的找到工作,刷面试题是必不可少的,了解最新企业招聘试题,可以让你面试更加的顺利.小编整理了一些2018年最新的Python面试题,来测测你技术的掌握度吧. 1.Python里面如何拷贝一个对象?(赋值,浅拷贝,深拷贝的区别) 答:赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个. 浅拷贝:创建一个新的对象,但它

MySQL面试必考知识点:揭秘亿级高并发数据库调优与最佳实践法则

做业务,要懂基本的SQL语句: 做性能优化,要懂索引,懂引擎: 做分库分表,要懂主从,懂读写分离... 数据库的使用,是开发人员的基本功,对它掌握越清晰越深入,你能做的事情就越多. 今天我们用10分钟,重点梳理一遍以下几方面: 数据库知识点汇总: 数据库事务特性和隔离级别: 详解关系型数据库.索引与锁机制: 数据库调优与最佳实践: 面试考察点及加分项. 知识点汇总 一.数据库的不同类型 1.常用的关系型数据库 Oracle:功能强大,主要缺点就是贵 MySQL:互联网行业中最流行的数据库,这不仅

【iOS开发-34】自己主动释放池@autoreleasepool的使用注意事项以及ARC机制——面试必考内容

自己主动释放池@autorelease面试频率可能会吧release还要高. (1)在自己主动释放池@autoreleasepool{}中alloc一个对象后(如p1).仍然须要用[p1 autorelease];不过这个语句和[p1 release];不同.后者表示把p1的retainCount-1,而前者只表示把p1放到自己主动释放池中返回一个self,自己主动释放池结束销毁时,统一对里面的对象引用计数retainCount-1. (2)@autoreleasepool{}能够任意创建.也能

【iOS开发-34】自动释放池@autoreleasepool的使用注意事项以及ARC机制——面试必考内容

自动释放池@autorelease面试频率可能会吧release还要高. (1)在自动释放池@autoreleasepool{}中alloc一个对象后(如p1),仍然需要用[p1 autorelease];只是这个语句和[p1 release];不同,后者表示把p1的retainCount-1,而前者仅仅表示把p1放到自动释放池中返回一个self,自动释放池结束销毁时,统一对里面的对象引用计数retainCount-1. (2)@autoreleasepool{}可以随意创建,也可以嵌套使用.

Android面试必考基础题

(1)<必考题>请写出Android系统架构有几层,分别是哪几层? 考点:Android系统架构 答案:有四层.分别是Linux内核.本地库和Java运行时环境.应用程序框架.应用程序. (2)<必考题>请简要介绍Android的四大组件? 考点:Android四大组件 答案:Android系统有四种组件,这四种组件构成了Android应用的框架,然后由Intent联系这四种组件.Activity用来显示Android的程序界面,一个应用往往有多个界面,所以一个应用中会有多个Act

面试必考三大排序算法C++代码(快速排序、归并排序、堆排序)

前两个为C++风格代码,后一个为C风格代码,除了输入输出,其它无差别,但C输入输出要比C++更快. 快速排序 1 #include <iostream> 2 using namespace std; 3 4 void swap(int num[], int i, int j) 5 { 6 int temp = num[i]; 7 num[i] = num[j]; 8 num[j] = temp; 9 } 10 11 int partition(int num[], int left, int

【iOS开发-33】学习手动内存管理临时抛弃ARC以及retain/assign知识——iOSproject师面试必考内容

我们为什么须要内存管理?当使用内存达到40M和45M时候会发出警告,假设不处理,占用内存达到120M时直接强制关闭程序. 所以出现闪退除了是程序出现逻辑错误,还有可能是内存使用过大. (1)创建一个对象的过程:先分配内存空间存储对象:初始化成员变量:返回对象的指针. (2)对象在创建时,内部会自己主动创建一个引用计数器retainCount,当retainCount=0时,系统会回收当前对象,retainCount是唯一推断标记.release会-1.retain会+1,retain后返回的是自