寫乙個刪除列表中重複元素的函式,要求去重後元素相對位置保持不變。
點評:這個題目在初中級python崗位面試的時候經常出現,題目源於《python cookbook》這本書第一章的第10個問題,有很多面試題其實都是這本書上的原題,所以建議大家有時間好好研讀一下這本書。
def dedup(items):
no_dup_items =
seen = set()
for item in items:
if item not in seen:
seen.add(item)
return no_dup_items
如果願意也可以把上面的函式改造成乙個生成器,**如下所示。
def dedup(items):
seen = set()
for item in items:
if item not in seen:
yield item
seen.add(item)
擴充套件:由於python中的集合底層使用雜湊儲存,所以集合的in
和not in
成員運算在效能上遠遠優於列表,所以上面的**我們使用了集合來儲存已經出現過的元素。集合中的元素必須是hashable
物件,因此上面的**在列表元素不是hashable
物件時會失效,要解決這個問題可以給函式增加乙個引數,該引數可以設計為返回雜湊碼或hashable
物件的函式。假設你使用的是官方的cpython,說出下面**的執行結果。
點評:下面的程式對實際開發並沒有什麼意義,但卻是cpython中的乙個大坑,這道題旨在考察面試者對官方的python直譯器到底了解到什麼程度。
a, b, c, d = 1, 1, 1000, 1000
print(a is b, c is d)
def foo():
e = 1000
f = 1000
print(e is f, e is d)
g = 1
print(g is a)
foo()
執行結果:
true false
true false
true
上面**中a is b
的結果是true
但c is d
的結果是false
,這一點的確讓人費解。cpython直譯器出於效能優化的考慮,把頻繁使用的整數物件用乙個叫small_ints
的物件池快取起來造成的。small_ints
快取的整數值被設定為[-5, 256]
這個區間,也就是說,在任何引用這些整數的地方,都不需要重新建立int
物件,而是直接引用快取池中的物件。如果整數不在該範圍內,那麼即便兩個整數的值相同,它們也是不同的物件。
cpython底層為了進一步提公升效能還做了另乙個設定,對於同乙個**塊中值不在small_ints
快取範圍內的整數,如果同乙個**塊中已經存在乙個值與其相同的整數物件,那麼就直接引用該物件,否則建立新的int
物件。需要大家注意的是,這條規則對數值型適用,但對字串則需要考慮字串的長度,這一點大家可以自行證明。
擴充套件:如果你用pypy(另一種python直譯器實現,支援jit,對cpython的缺點進行了改良,在效能上優於cpython,但對三方庫的支援略差)來執行上面的**,你會發現所有的輸出都是true。
python基礎面試
一 給定乙個字串,將字串的偶數字的字母替換成 二 輸入三個整數x,y,z,請把這三個數由小到大輸出。三 計算字串中字元出現的次數 l hu21w3ad234eww3123478965hjawk1212 d for i in l d i l.count i print d dn 0 for n in ...
面試準備基礎2
對於python高階中的面試準備2 1 迭代器 迭代是訪問集合元素的一種方式。迭代器是乙個可以記住遍歷的位置的物件。迭代器物件從集合的第乙個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退。可迭代物件 直接作用於for迴圈的資料型別 一類是集合資料型別,如list tuple dic...
python基礎語法面試 python基礎面試題
1 python中的資料型別?不可變資料型別?可變資料型別?2 python中,開啟檔案語法?3 endswith 4 下列 輸出結果?importcopy a 1,2,3,4,a b b ac copy.copy a d copy.deepcopy a 5 read readline readli...