首頁  >  文章  >  後端開發  >  python面試中必考的程式碼題

python面試中必考的程式碼題

不言
不言轉載
2019-02-23 10:25:204525瀏覽

python面試中必考的程式碼題

這篇文章帶給大家的內容是關於python面試中必考的程式碼題,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

相關文章推薦:《2020年python面試題總結(最新)

#問題一:以下的程式碼的輸出將是什麼? 說出你的答案並解釋。   

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 中,類別變數在內部是作為字典處理的。如果一個變數的名字沒有在目前類別的字典中發現,將搜尋祖先類別(例如父類別)直到被引用的變數名稱被找到(如果這個被引用的變數名稱既沒有在自己所在的類別又沒有在祖先類別中找到,會引發一個AttributeError 異常)。

因此,在父類別中設定 x = 1 會使得類別變數 X 在引用該類別和其任何子類別中的值為 1。這就是因為第一個 print 語句的輸出是 1 1 1。

隨後,如果任何它的子類別重寫了該值(例如,我們執行語句 Child1.x = 2),然後,該值僅在子類別中被改變。這就是為什麼第二個 print 語句的輸出是 1 2 1。

最後,如果該值在父類別中被改變(例如,我們執行語句Parent.x = 3),這個改變會影響到任何未重寫該值的子類別當中的值(在這個範例中被影響的子類別是Child2)。這就是為什麼第三個 print 輸出是 3 2 3。

問題二:以下的程式碼的輸出會是什麼? 說出你的答案並解釋?

def p1(x,y):
    print("%s/%s = %s" % (x, y, x/y))

def p2(x,y):
    print("%s//%s = %s" % (x, y, x//y))

p1(5,2)
p1(5.,2)
p2(5,2)
p2(5.,2.)
5/2 = 2
5.0/2.0=2.5
5/2=2
5/2=2

答案

這個答案實際上依賴你使用的是 Python 2 還是 Python 3。

在Python 3 中,期望的輸出是:

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

在Python 2 中,儘管如此,以上程式碼的輸出將是:

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``。

注意,儘管如此,你可以在Python 2 中重載這一行為(例如達到你想在Python 3 中的相同結果),透過新增以下導入:

from__future__ import pision
也需要注意的是「雙劃線」(//)運算子將一直執行整除,而不管運算元的類型,這就是為什麼5.0//2.0 值為2.0。

註:在Python 3 中,/ 操作符是做浮點除法,而// 是做整除(即商沒有餘數,例如10 / / 3 其結果就為3,餘數會被截除掉,而(-7) // 3 的結果卻是-3。這個演算法與其它很多程式語言不一樣,需要注意,它們的整除運算會向0的方向取值。而在Python 2 中,/ 就是整除,也就是和Python 3 中的// 運算子一樣,)

問題三:以下程式碼會輸出什麼?

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

答案
以上程式碼將輸出[ ],並且不會導致一個IndexError。

正如人們所期望的,試圖存取一個超過列表索引值的成員將導致IndexError(例如訪問以上列表的list[10])。儘管如此,試圖訪問一個列表的以超出列表成員數作為開始索引的切片將不會導致IndexError,並且將僅返回一個空列表。

一個討厭的小問題是它會導致出現bug ,並且這個問題是難以追蹤的,因為它在運行時不會引發錯誤。

問題四:以下的程式碼的輸出將是什麼?說出你的答案並解釋?

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 的閉包的後期綁定導致的late binding,這意味著在閉包中的變數是在內部函數被調用的時候被查找。所以結果是,當任何multipliers() 返回的函數被調用,在那時,i 的值是在它在被調用時的周圍作用域中查找,到那時,無論哪個返回的函數被調用,for 循環都已經完成了,i 最後的值是3,因此,每個返回的函數multiplies 的值都是3。因此一個等於2 的值被傳遞進以上程式碼,它們將會傳回一個值6 (例如: 3 x 2)。

(顺便说下,正如在 The Hitchhiker’s Guide to Python 中指出的,这里有一点普遍的误解,是关于 lambda 表达式的一些东西。一个 lambda 表达式创建的函数不是特殊的,和使用一个普通的 def 创建的函数展示的表现是一样的。)

这里有两种方法解决这个问题

最普遍的解决方案是创建一个闭包,通过使用默认参数立即绑定它的参数。例如:

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

另外一个选择是,你可以使用 functools.partial 函数

from functools import partial
from operator import mul

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

问题五:以下的代码的输出将是什么? 说出你的答案并解释?

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’]。认为 list 的参数会在 extendList 每次被调用的时候会被设置成它的默认值 [ ]。

尽管如此,实际发生的事情是,新的默认列表仅仅只在函数被定义时创建一次。随后当 extendList 没有被指定的列表参数调用的时候,其使用的是同一个列表。这就是为什么当函数被定义的时候,表达式是用默认参数被计算,而不是它被调用的时候。

因此,list1 和 list3 是操作的相同的列表。而 "`list2是操作的它创建的独立的列表(通过传递它自己的空列表作为list"参数的值)。

extendList 函数的定义可以做如下修改,但,当没有新的 list 参数被指定的时候,会总是开始一个新列表,这更加可能是一直期望的行为。

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

使用这个改进的实现,输出将是:

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

相关学习推荐:python视频教程

以上是python面試中必考的程式碼題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除