這篇文章主要講解了“Python經(jīng)典面試題有哪些”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Python經(jīng)典面試題有哪些”吧!
創(chuàng)新互聯(lián)是少有的成都網(wǎng)站建設(shè)、做網(wǎng)站、營銷型企業(yè)網(wǎng)站、微信小程序、手機(jī)APP,開發(fā)、制作、設(shè)計(jì)、買鏈接、推廣優(yōu)化一站式服務(wù)網(wǎng)絡(luò)公司,于2013年開始,堅(jiān)持透明化,價(jià)格低,無套路經(jīng)營理念。讓網(wǎng)頁驚喜每一位訪客多年來深受用戶好評(píng)
Python面試題(一)之交換變量值
平時(shí)時(shí)不時(shí)會(huì)面面實(shí)習(xí)生,大多數(shù)的同學(xué)在學(xué)校里都已經(jīng)掌握了Python。面試的時(shí)候要求同學(xué)們實(shí)現(xiàn)一個(gè)簡單的函數(shù),交換兩個(gè)變量的值,大多數(shù)的同學(xué)給出的都是如下的答案
實(shí)際上,Python中還有更簡潔的更具Python風(fēng)格的實(shí)現(xiàn),如下
相比前一種方法,后一種方法節(jié)省一個(gè)中間變量,在性能上也優(yōu)于前一種方法。
我們從Python的字節(jié)碼來深入分析一下原因。
dis是個(gè)反匯編工具,將Python代碼翻譯成字節(jié)碼指令。這里的輸出如下
通過字節(jié)碼可以看到,swap1和swap2最大的區(qū)別在于,swap1中通過ROT_TWO交換棧頂?shù)膬蓚€(gè)元素實(shí)現(xiàn)x和y值的互換,swap2中引入了tmp變量,多了一次LOAD_FAST, STORE_FAST的操作。執(zhí)行一個(gè)ROT_TWO指令比執(zhí)行一個(gè)LOAD_FAST+STORE_FAST的指令快,這也是為什么swap1比swap2性能更好的原因。
Python面試題(二) is 和 == 的區(qū)別
面試實(shí)習(xí)生的時(shí)候,當(dāng)問到 is 和 == 的區(qū)別時(shí),很多同學(xué)都答不上來,搞不清兩者什么時(shí)候返回一致,什么時(shí)候返回不一致。本文我們來看一下這兩者的區(qū)別。
我們先來看幾個(gè)例子:
上面的輸出結(jié)果中為什么有的 is 和 == 的結(jié)果相同,有的不相同呢?我們來看下官方文檔中對(duì)于 is 和 == 的解釋。
官方文檔中說 is 表示的是對(duì)象標(biāo)示符是否一致,也就是比較兩個(gè)對(duì)象在內(nèi)存中的地址是否一樣,而 == 是用來檢查兩個(gè)對(duì)象是否相等。
我們?cè)跈z查 a is b 的時(shí)候,其實(shí)相當(dāng)于檢查 id(a) == id(b)。而檢查 a == b 的時(shí)候,實(shí)際是調(diào)用了對(duì)象 a 的 __eq()__ 方法,a == b 相當(dāng)于 a.__eq__(b)。
一般情況下,如果 a is b 返回True的話,即 a 和 b 指向同一塊內(nèi)存地址的話,a == b 也返回True,即 a 和 b 的值也相等。
好了,看明白上面的解釋后,我們來看下前面的幾個(gè)例子
打印出 id(a) 和 id(b) 后就很清楚了。只要 a 和 b 的值相等,a == b 就會(huì)返回True,而只有 id(a) 和 id(b) 相等時(shí),a is b 才返回 True。
這里還有一個(gè)問題,為什么 a 和 b 都是 "hello" 的時(shí)候,a is b 返回True,而 a 和 b都是 "hello world" 的時(shí)候,a is b 返回False呢?
這是因?yàn)榍耙环N情況下Python的字符串駐留機(jī)制起了作用。對(duì)于較小的字符串,為了提高系統(tǒng)性能Python會(huì)保留其值的一個(gè)副本,當(dāng)創(chuàng)建新的字符串的時(shí)候直接指向該副本即可。所以 "hello" 在內(nèi)存中只有一個(gè)副本,a 和 b 的 id 值相同,而 "hello world" 是長字符串,不駐留內(nèi)存,Python中各自創(chuàng)建了對(duì)象來表示 a 和 b,所以他們的值相同但 id 值不同。
同學(xué)指出:intern機(jī)制和字符串長短無關(guān),在交互模式下,每行字符串字面量都會(huì)申請(qǐng)一個(gè)新字符串,但是只含大小寫字母、數(shù)字和下劃線的會(huì)被intern,也就是維護(hù)了一張dict來使得這些字符串全局唯一)
總結(jié)一下,is 是檢查兩個(gè)對(duì)象是否指向同一塊內(nèi)存空間,而 == 是檢查他們的值是否相等??梢钥闯?,is 是比 == 更嚴(yán)格的檢查,is 返回True表明這兩個(gè)對(duì)象指向同一塊內(nèi)存,值也一定相同。
看到這里,大家是不是搞懂了 is 和 == 的區(qū)別呢?
那我們深入一步來思考一下下面這個(gè)問題:
Python里和None比較時(shí),為什么是 is None 而不是 == None 呢?
伙伴們會(huì)的可以在評(píng)論區(qū)留言哦~!
Python面試題(三)可變對(duì)象和不可變對(duì)象
上一個(gè)面試題:Python面試之 is 和 == 的區(qū)別的最后留了一個(gè)問題:
Python里和None比較時(shí),為什么是 is None 而不是 == None 呢?
這是因?yàn)镹one在Python里是個(gè)單例對(duì)象,一個(gè)變量如果是None,它一定和None指向同一個(gè)內(nèi)存地址。而 == None背后調(diào)用的是__eq__,而__eq__可以被重載,下面是一個(gè) is not None但 == None的例子
Python中有可變對(duì)象和不可變對(duì)象之分。可變對(duì)象創(chuàng)建后可改變但地址不會(huì)改變,即變量指向的還是原來的變量;不可變對(duì)象創(chuàng)建之后便不能改變,如果改變則會(huì)指向一個(gè)新的對(duì)象。
Python中dict、list是可變對(duì)象,str、int、tuple、float是不可變對(duì)象。
來看一個(gè)字符串的例子
上面的例子里,修改a指向的對(duì)象的值會(huì)導(dǎo)致拋出異常。
執(zhí)行 a = a + " world"時(shí),先計(jì)算等號(hào)右邊的表達(dá)式,生成一個(gè)新的對(duì)象賦值到變量a,因此a指向的對(duì)象發(fā)生了改變,id(a) 的值也與原先不同。
再來看一個(gè)列表的例子
上面對(duì)a修改元素、添加元素,變量a還是指向原來的對(duì)象。
將a賦值給b后,變量b和a都指向同一個(gè)對(duì)象,因此修改b的元素值也會(huì)影響a。
變量c是對(duì)b的切片操作的返回值,切片操作相當(dāng)于淺拷貝,會(huì)生成一個(gè)新的對(duì)象,因此c指向的對(duì)象不再是b所指向的對(duì)象,對(duì)c的操作不會(huì)改變b的值。
理解了上面不可變對(duì)象和可變對(duì)象的區(qū)別后,我們?cè)賮砜匆粋€(gè)有趣的問題
明明group1和group2是不同的對(duì)象(id值不同),為什么調(diào)用group2的add_member方法會(huì)影響group1的members?
其中的奧妙就在于__init__函數(shù)的第二個(gè)參數(shù)是默認(rèn)參數(shù),默認(rèn)參數(shù)的默認(rèn)值在函數(shù)創(chuàng)建的時(shí)候就生成了,每次調(diào)用都是用了這個(gè)對(duì)象的緩存。我們檢查id(group1.mebers)和id(group2.members),可以發(fā)現(xiàn)他們是相同的
print(id(group1.members)) # 輸出 140127132522040
print(id(group2.members)) # 輸出 140127132522040
所以,group1.members和group2.members指向了同一個(gè)對(duì)象,對(duì)group2.members的修改也會(huì)影響group1.members。
感謝各位的閱讀,以上就是“Python經(jīng)典面試題有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)Python經(jīng)典面試題有哪些這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!