Python筆試面試題小結
1.字串處理
將字串中的數字替換成其兩倍的值,例如:
修改前:"AS7G123m (d)F77k"
修改後:"AS14G246m (d)F154k"
個人思路:先用正則表示式將其中的數字匹配出來進行乘2操作,然後將字串根據其中的數字進行切割,得到一個字元列表,最終將乘以2後的數字和原有的字元進行拼接得到最後的結果。(我腦子比較笨,想不到別的,如果您有更好更簡便的方法,希望可以分享一下!)
import re text = "AS7G123m (d)F77k" nums = re.findall(r'(\d+)',text) # 取出字串中數字 double_nums = [2 * int(i) for i in nums] # 乘以2 the_str = [] # 字元列表 for i in nums: the_str.append(text.split(i,1)[0]) text = text.split(i,1)[1] result = "" # 結果 for i in range(len(double_nums)): result += the_str[i] + str(double_nums[i]) result += text print(result)
2.Python傳參是值傳遞還是引用傳遞?
答案是Python中傳遞引數是引用傳遞,那麼要證明是引用傳遞呢?可以參考下面這個例子:
def f(x): print(id(x)) a = 1 print(id(a)) f(a) # 140716760159264 # 140716760159264
這裡分別列印了兩個地址,一個是物件a的地址,一個是傳入的引數x的地址,可以看到兩個地址是一樣的,這也就說明Python中的傳參使用的引用傳遞!需要注意的是:對於不可變型別,在函式中對其操作並不會對原物件產生影響,但對於可變型別,在函式中對其操作則可能會改變其值,如下:
1)傳入的引數是不可變型別:
def f(x): x += "666" # 這裡會建立一個新的物件 print(x) s = "777" # 字串不可變 print(s) f(s) print(s) # 777 # 777666 # 777
2)傳入的引數是可變型別:
def f(x): x.append(4) # 修改原物件的值 print(x) s = [1,2,3] # 列表可變 print(s) f(s) print(s) # [1,3] # [1,3,4] # [1,4]
3.淺拷貝與深拷貝的那些事
在Python中,淺拷貝與深拷貝是一定要分清楚的!對於淺拷貝和深拷貝,可以這麼理解:
1)淺拷貝:建立一個物件,但其中包含的是原物件中所包含項的引用,如果用引用的方式修改了其中的物件,就會對原物件進行改變。
2)深拷貝:建立一個物件,並且遞迴複製原物件中所包含的物件,此時修改資料不會對原物件產生影響。
在下面的程式碼中包含了賦值、淺拷貝和深拷貝,在Python中賦值即引用物件,所以對c操作也就是對原物件a進行操作,對於淺拷貝物件b和d,對其中的引用進行操作會改變對a中的物件,而對深拷貝物件e進行操作就與原物件a無關了。
import copy a = [1,[2],3] b = a[:] # 使用切片操作,淺拷貝 c = a # 賦值操作,即引用 d = a.copy() # 淺拷貝 e = copy.deepcopy(a) # 深拷貝 b.append(4) c.append(5) d.append(6) d[1].append(2) e.append(7) e[1].append(3) print(a) # [1,[2,2],5] print(b) # [1,4] print(c) # [1,5] print(d) # [1,6] print(e) # [1,3],7]
4.Python一行式能幹嘛?
下面是一些Python一行式的示例,從中可以看出Python是非常簡潔和強大的!
1)一行程式碼輸出一百以內的奇數:
print([x for x in range(100) if x % 2])
2)一行程式碼求水仙花數:
print([x for x in range(100,1000) if int(str(x)[0])**3 + int(str(x)[1])**3 + int(str(x)[2])**3 == x])
3)一行程式碼列印九九乘法表:
print("".join(["{} * {} = {}\t".format(x,y,x * y) if x != y else "{} * {} = {}\n".format(x,x * y) for x in range(1,10) for y in range(1,x + 1)]))
4)一行程式碼實現IP地址轉換,如將192.168.12.1轉換成0b11000000 10101000 00001100 00000001:
print("0b"+" ".join(("00000000" + bin(int(i)).replace("0b",""))[-8:] for i in ip.split(".")))
5)一行程式碼求1到10的和:
from functools import reduce; print(reduce(lambda x,y: x + y,[i for i in range(1,11)]))
5.下面這段程式碼的結果是什麼?
def mul(): return [lambda x: x * i for i in range(4)] print([m(2) for m in mul()])
以上這段程式碼輸出的結果是[6,6,6],而不是[0,4,6]!
產生這個問題的原因在於Python閉包的延遲繫結。這意味著內部函式被呼叫時,引數的值在閉包內進行查詢。所以當mul()返回的函式被呼叫時,i的值會在返回的函式裡查詢,而for迴圈完成後i的值為3,也就是i最終賦值為3。因此,每次返回的函式乘以傳入的值就是最後的結果,得到的結果就是[6,6]。
如果要解決這個問題,可以參考以下方法:
1)使用Python生成器。
def mul(): for i in range(4): yield lambda x: x * i print([m(2) for m in mul()])
2)創造一個閉包,利用預設函式進行繫結。
def mul(): return [lambda x,i=i: x * i for i in range(4)] print([m(2) for m in mul()])
這篇文章先介紹到這,後期我們小編會為大家分享更多的文章。