1. 程式人生 > >2018最經典的python面試題

2018最經典的python面試題

1:Python 如何實現單例模式? Python 有兩種方式可以實現單例模式,下面兩個例子使用了不同的方式實現單 例模式: 1. class Singleton(type): def __init__(cls, name, bases, dict): super(Singleton, cls).__init__(name, bases, dict) cls.instance = None def __call__(cls, *args, **kw): if cls.instance is None: cls.instance = super(Singleton, cls).__call__(*args, **kw) return cls.instance class MyClass(object): __metaclass__ = Singleton print MyClass() print MyClass() 2. 使用 decorator 來實現單例模式 def singleton(cls): instances = {} def getinstance(): if cls not in instances: instances[cls] = cls() return instances[cls] return getinstance @singleton class MyClass: … 2:什麼是 lambda 函式? Python 允許你定義一種單行的小函式。定義 lambda 函式的形式如下: labmda 參 數:表示式 lambda 函式預設返回表示式的值。你也可以將其賦值給一個變數。 lambda 函式可以接受任意個引數,包括可選引數,但是表示式只有一個: >>> g = lambda x, y: x*y >>> g(3,4) 12 >>> g = lambda x, y=0, z=0: x+y+z >>> g(1) 1 >>> g(3, 4, 7) 14 也能夠直接使用 lambda 函式,不把它賦值給變數: >>> (lambda x,y=0,z=0:x+y+z)(3,5,6) 14 如果你的函式非常簡單,只有一個表示式,不包含命令,可以考慮 lambda 函式。 否則,你還是定義函式才對,畢竟函式沒有這麼多限制。 3:Python 是如何進行型別轉換的? Python 提供了將變數或值從一種型別轉換成另一種型別的內建函式。 int 函式能 夠將符合數學格式數字型字串轉換成整數。否則,返回錯誤資訊。 >>> int(”34″) 34 >>> int(”1234ab”) #不能轉換成整數 ValueError: invalid literal for int(): 1234ab 函式 int 也能夠把浮點數轉換成整數,但浮點數的小數部分被截去。 >>> int(34.1234) 34 >>> int(-2.46) -2 函式°oat 將整數和字串轉換成浮點數: >>> float(”12″) 12.0 >>> float(”1.111111″) 1.111111 函式 str 將數字轉換成字元: >>> str(98) ‘98′ >>> str(”76.765″) ‘76.765′ 整數 1 和浮點數 1.0 在 python 中是不同的。雖然它們的值相等的,但卻屬於不 同的型別。這兩個數在計算機的儲存形式也是不一樣。 4:Python 如何定義一個函式 函式的定義形式如 下: def <name>(arg1, arg2,… argN): <statements> 函式的名字也必須以字母開頭,可以包括下劃線“ ”,但不能把 Python 的 關鍵字定義成函式的名字。函式內的語句數量是任意的,每個語句至少有 一個空格的縮排,以表示此語句屬於這個函式的。縮排結束的地方,函式 自然結束。 下面定義了一個兩個數相加的函式: >>> def add(p1, p2): print p1, “+”, p2, “=”, p1+p2 >>> add(1, 2) 1 + 2 = 3 函式的目的是把一些複雜的操作隱藏,來簡化程式的結構,使其容易 閱讀。函式在呼叫前,必須先定義。也可以在一個函式內部定義函式,內 部函式只有在外部函式呼叫時才能夠被執行。程式呼叫函式時,轉到函式 內部執行函式內部的語句,函式執行完畢後,返回到它離開程式的地方, 執行程式的下一條語句。 5:Python 是如何進行記憶體管理的? Python 的記憶體管理是由 Python 得直譯器負責的,開發人員可以從記憶體管理事務中解放出來, 致力於應用程式的開發,這樣就使得開發的程式錯誤更少,程式更健壯,開發週期更短 6:如何反序的迭代一個序列?howdoIiterate overasequenceinreverse order 如果是一個 list, 最快的解決方案是: list.reverse() try: for x in list: “do something with x” finally: list.reverse() 如果不是 list, 最通用但是稍慢的解決方案是: for i in range(len(sequence)-1, -1, -1): x = sequence[i] <do something with x> 7:Python 裡面如何實現 tuple 和 list 的轉換? 函式 tuple(seq)可以把所有可迭代的(iterable)序列轉換成一個 tuple, 元素 不變,排序也不變。 例如,tuple([1,2,3])返回(1,2,3), tuple(’abc’)返回(’a’.’b',’c'). 如果引數已經是一個 tuple 的話,函式不做任何拷貝而直接返回原來的物件,所 以在不確定物件是不是 tuple 的時候來呼叫 tuple()函式也不是很耗費的。 函式 list(seq)可以把所有的序列和可迭代的物件轉換成一個 list,元素不變, 排序也不變。 例如 list([1,2,3])返回(1,2,3), list(’abc’)返回['a', 'b', 'c']。如果 引數是一個 list, 她會像 set[:]一樣做一個拷貝 8:Python 面試題:請寫出一段 Python 程式碼實現刪除一個 list 裡面的重複元素 可以先把 list 重新排序,然後從 list 的最後開始掃描,程式碼如下: if List: List.sort() last = List[-1] for i in range(len(List)-2, -1, -1): if last==List[i]: del List[i] else: last=List[i] 9:Python 檔案操作的面試題 1. 如何用 Python 刪除一個檔案? 使用 os.remove(filename)或者 os.unlink(filename); 2. Python 如何 copy 一個檔案? shutil 模組有一個 copyfile 函式可以實現檔案拷貝 10:Python 裡面如何生成隨機數? 標準庫 random 實現了一個隨機數生成器,例項程式碼如下: import random random.random() 它會返回一個隨機的 0 和 1 之間的浮點數 11:如何用 Python 來發送郵件? 可以使用 smtplib 標準庫。 以下程式碼可以在支援 SMTP 監聽器的伺服器上執行。 import sys, smtplib fromaddr = raw_input(”From: “) toaddrs = raw_input(”To: “).split(’,') print “Enter message, end with ^D:” msg = ” while 1: line = sys.stdin.readline() if not line: break msg = msg + line # 傳送郵件部分 server = smtplib.SMTP(’localhost’) server.sendmail(fromaddr, toaddrs, msg) server.quit() 12:Python 裡面如何拷貝一個物件? 一般來說可以使用 copy.copy()方法或者 copy.deepcopy()方法,幾乎所有的對 象都可以被拷貝 一些物件可以更容易的拷貝,Dictionaries 有一個 copy 方法: newdict = olddict.copy() 13:有沒有一個工具可以幫助查詢 python 的 bug 和進行靜態的程式碼分析? 有,PyChecker 是一個 python 程式碼的靜態分析工具,它可以幫助查詢 python 代 碼的 bug, 會對程式碼的複雜度和格式提出警告 Pylint 是另外一個工具可以進行 coding standard 檢查。 14:如何在一個 function 裡面設定一個全域性的變數? 解決方法是在 function 的開始插入一個 global 宣告: def f() global x 14:有兩個序列 a,b,大小都為 n,序列元素的值任意整形數,無序;要求:通過 交換 a,b 中的元素,使[序列 a 元素的和]與[序列 b 元素的和]之間的差最小。 1. 將兩序列合併為一個序列,並排序,為序列 Source 2. 拿出最大元素 Big,次大的元素 Small 3. 在餘下的序列 S[:-2]進行平分,得到序列 max,min 4. 將 Small 加到 max 序列,將 Big 加大 min 序列,重新計算新序列和,和大的 為 max,小的為 min。 Python 程式碼 def mean( sorted_list ): if not sorted_list: return (([],[])) big = sorted_list[-1] small = sorted_list[-2] big_list, small_list = mean(sorted_list[:-2]) big_list.append(small) small_list.append(big) big_list_sum = sum(big_list) small_list_sum = sum(small_list) if big_list_sum > small_list_sum: return ( (big_list, small_list)) else: return (( small_list, big_list)) tests = [ [1,2,3,4,5,6,700,800], [10001,10000,100,90,50,1], range(1, 11), [12312, 12311, 232, 210, 30, 29, 3, 2, 1, 1] ] for l in tests: l.sort() print print “Source List:\t”, l l1,l2 = mean(l) print “Result List:\t”, l1, l2 print “Distance:\t”, abs(sum(l1)-sum(l2)) print ‘-*’*40 輸出結果 Python 程式碼 Source List: [1, 2, 3, 4, 5, 6, 700, 800] Result List: [1, 4, 5, 800] [2, 3, 6, 700] Distance: 99 -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-* Source List: [1, 50, 90, 100, 10000, 10001] Result List: [50, 90, 10000] [1, 100, 10001] Distance: 38 -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-* Source List: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Result List: [2, 3, 6, 7, 10] [1, 4, 5, 8, 9] Distance: 1 -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-* Source List: [1, 1, 2, 3, 29, 30, 210, 232, 12311, 12312] Result List: [1, 3, 29, 232, 12311] [1, 2, 30, 210, 12312] Distance: 21 -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-* 15:用 Python 匹配 HTMLtag 的時候,<.*>和<.*?>有什麼區別? 當重複匹配一個正則表示式時候, 例如<.*>, 當程式執行匹配的時候,會返回 最大的匹配值 例如: import re s = ‘<html><head><title>Title</title>’ print(re.match(’<.*>’, s).group()) 會返回一個匹配<html><head><title>Title</title>而不是<html> 而 import re s = ‘<html><head><title>Title</title>’ print(re.match(’<.*?>’, s).group()) 則會返回<html> <.*>這種匹配稱作貪心匹配 <.*?>稱作非貪心匹配 16:Python 裡面 search()和 match()的區別? match()函式只檢測 RE 是不是在 string 的開始位置匹配, search()會掃描整 個 string 查詢匹配, 也就是說 match()只有在 0 位置匹配成功的話才有返回, 如果不是開始位置匹配成功的話,match()就返回 none 例如: print(re.match(’super’, ’superstition’).span())會返回(0, 5) 而 print(re.match(’super’, ‘insuperable’))則返回 None search()會掃描整個字串並返回第一個成功的匹配 例如:print(re.search(’super’, ’superstition’).span())返回(0, 5) print(re.search(’super’, ‘insuperable’).span())返回(2, 7) 17:如何用 Python 來進行查詢和替換一個文字字串? 可以使用 sub()方法來進行查詢和替換,sub 方法的格式為:sub(replacement, string[, count=0]) replacement 是被替換成的文字 string 是需要被替換的文字 count 是一個可選引數,指最大被替換的數量 例子: import re p = re.compile(’(blue|white|red)’) print(p.sub(’colour’,'blue socks and red shoes’)) print(p.sub(’colour’,'blue socks and red shoes’, count=1)) 輸出: colour socks and colour shoes colour socks and red shoes subn()方法執行的效果跟 sub()一樣,不過它會返回一個二維陣列,包括替換後 的新的字串和總共替換的數量 例如: import re p = re.compile(’(blue|white|red)’) print(p.subn(’colour’,'blue socks and red shoes’)) print(p.subn(’colour’,'blue socks and red shoes’, count=1)) 輸出 (’colour socks and colour shoes’, 2) (’colour socks and red shoes’, 1) 18:介紹一下 except 的用法和作用? Python 的 except 用來捕獲所有異常,因為 Python 裡面的每次錯誤都會丟擲 一 個異常,所以每個程式的錯誤都被當作一個執行時錯誤。 一下是使用 except 的一個例子: try: foo = opne(”file”) #open 被錯寫為 opne except: sys.exit(”could not open file!”) 因為這個錯誤是由於 open 被拼寫成 opne 而造成的,然後被 except 捕獲,所以 debug 程式的時候很容易不知道出了什麼問題 下面這個例子更好點: try: foo = opne(”file”) # 這時候 except 只捕獲 IOError except IOError: sys.exit(”could not open file”) 19:Python 中 pass 語句的作用是什麼? pass 語句什麼也不做,一般作為佔位符或者建立佔位程式,pass 語句不會執行 任何操作,比如: while False: pass pass 通常用來建立一個最簡單的類: class MyEmptyClass: pass pass 在軟體設計階段也經常用來作為 TODO,提醒實現相應的實現,比如: def initlog(*args): pass #please implement this 20:介紹一下 Python 下 range()函式的用法? 如果需要迭代一個數字序列的話,可以使用 range()函式,range()函式可以生 成等差級數。 如例: for i in range(5) print(i) 這段程式碼將輸出 0, 1, 2, 3, 4 五個數字 range(10)會產生 10 個值, 也可以讓 range()從另外一個數字開始,或者定義 一個不同的增量,甚至是負數增量 range(5, 10)從 5 到 9 的五個數字 range(0, 10, 3) 增量為三, 包括 0,3,6,9 四個數字 range(-10, -100, -30) 增量為-30, 包括-10, -40, -70 可以一起使用 range()和 len()來迭代一個索引序列 例如: a = ['Nina', 'Jim', 'Rainman', 'Hello'] for i in range(len(a)): print(i, a[i])