1. 程式人生 > 程式設計 >Python筆試面試題小結

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()])

這篇文章先介紹到這,後期我們小編會為大家分享更多的文章。