Python开发面试题:面试中 8 个必考问题

‘金三银四’ 工作的人没有不知道的吧,其实7月也是跳槽面试的高峰期,咱们的学生大军也加入了找工作的浪潮。这里根据经验和实际情况总结了一下在Python面试中,关于Python开发面试题必考的8个问题,有需要的小伙伴,敲黑板认真看哦!

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

def extendList(val, list=[]): list.append(val) return listlist1 = extendList(10)list2 = extendList(123,[])list3 = extendList( a )print "list1 = %s" % list1print "list2 = %s" % list2print "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 ]

Python开发面试题目: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 partialfrom operator import muldef multipliers(): return [partial(mul, i) for i in range(4)]

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

class Parent(object): x = 1class Child1(Parent): passclass Child2(Parent): passprint Parent.x, Child1.x, Child2.xChild1.x = 2print Parent.x, Child1.x, Child2.xParent.x = 3print Parent.x, Child1.x, Child2.x

输出结果将是:

1 1 11 2 13 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 = 25.0/2 = 2.55//2 = 25.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.55.0/2 = 2.55//2 = 25.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 = [ [ ] ] * 5list # 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开发面试题大家有没有更好的补充呢?你们在Python面试中有遇到过什么有趣的事呢?欢迎留言!

原文地址:https://www.cnblogs.com/cherry-tang/p/11076280.html

时间: 2024-08-28 23:07:45

Python开发面试题:面试中 8 个必考问题的相关文章

Python 开发面试题

Python部分 将一个字符串逆序,不能使用反转函数 求从10到100中能被3或5整除的数的和 What is Python? What are the benefits of using Python? What is PEP 8? What is pickling and unpickling? How Python is interpreted? What are the tools that help to find bugs or perform static analysis? Wh

[译]Python面试中8个必考问题

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&quo

大公司移动前端开发面试题——做转盘

"如果有个做转盘的需求,你准备怎么做?设计师只会提供一个转盘的图片,其余都需要你完成,不能用框架和类库." "这个转盘没有惯性的需求,只要求在手机上,用手指拖转盘,能让转盘跟随手指转起来即可." 这是我在面试前端开发人员时,经常会问到的一道题.转盘是类似上图的样子. 博主之前在M公司和C公司的时候,经常用这题面试移动前端开发工程师.M公司的产品和设计是美国团队,在个别项目上UI设计比较大胆脱俗,对前端开发人员有较高的要求.C公司的只会JS的前端开发人员占比较大,产品

C/C++嵌入式开发面试题

C/C++嵌入式开发面试题 预处理器(Preprocessor) 1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在这想看到几件事情: 1). #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等) 2). 懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的. 3). 意识

oracle 数据库开发面试题

最近参加了4.5场面试,总结一下竞聘oracle 开发岗位最常问到哪些问题: 1.delete 与 truncate 区别? 1)truncate 是DDL语句,delete 是DML语句: 2)truncate 速度远快于 delete: 原因是:当我们执行delete操作时所有表数据先被copy到回滚表空间,数据量不同花费时间长短不一.而truncate是直接删除数据不进回滚表空间. 3)接(2)这也就导致了delete数据后我们可以运行rollback进行数据回滚,而truncate则是永

Web开发面试题

标签:Web开发面试题 HTML+CSS1.对WEB标准以及W3C的理解与认识标签闭合.标签小写.不乱嵌套.提高搜索机器人搜索几率.使用外 链css和js脚本.结构行为表现的分离.文件下载与页面速度更快.内容能被更多的用户所访问.内容能被更广泛的设备所访问.更少的代码和组件,容易维 护.改版方便,不需要变动页面内容.提供打印版本而不需要复制内容.提高网站易用性: 2.xhtml和html有什么区别HTML是一种基本的WEB网页设计语言,XHTML是一个基于XML的置标语言最主要的不同:XHTML

大公司移动前端开发面试题——做转盘[参考代码]

题目在此 http://www.cnblogs.com/arfeizhang/p/turntable.html 这几天一直在忙,终于找到时间把参考代码放出来了.大家参考一下. 参考代码考虑到让入行不久的前端也看得懂,没有进行封装.变量名也没有进行简写,尽量一看就明白. 图片随手在网上截的,也许没有对准圆心.这段代码只考虑了webkit内核的浏览器,没做兼容.重在让大家弄懂原理. :P 如果感到有些卡帧,可能是转盘图片带来的效果.在调试器上试过,能维持50-60帧,流畅度还是让人满意的.在LG G

前端开发面试题收集 JS

前端开发面试题收集-JS篇 收集经典的前端开发面试题 setTimeout的时间定义为0有什么用? javascript引擎是单线程处理任务的,它把任务放在队列中,不会同步执行,必须在完成一个任务后才开始另一个任务. 由于setTimeout可以把任务从某个队列中跳出成为新队列,因此能够得到期望的结果. 怎么理解this this指向的总是调用函数的那个对象. this一般情况下,是全局对象Global. 什么是闭包 闭包是一个概念,我的理解是函数里的函数,能够读取函数内部变量的函数. 就是将函

【面试】iOS 开发面试题(二)

1. 我们说的oc是动态运行时语言是什么意思? 答案:多态. 主要是将数据类型的确定由编译时,推迟到了运行时. 这个问题其实浅涉及到两个概念,运行时和多态. 简单来说,运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法. 多态:不同对象以自己的方式响应相同的消息的能力叫做多态.意思就是假设生物类(life)都用有一个相同的方法-eat; 那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,但是调用是我们只需调用各自的eat方法. 也就是不同的对象以自己的