天天看點

python面試題coding=utf8

  1. 什麼是lambda函數,它有什麼好處?

    lambda 函數是一個可以接收任意多個參數(包括可選參數)并且傳回單個表達式值的函數

  • lambda 函數比較輕便, 即用即仍, 很适合需要完成一項功能, 但是此功能隻在此一處使用, 連名字都很随意的情況下;
  • 匿名函數, 一般用來給 filter, map 這樣的函數式程式設計服務;
  • 作為回調函數, 傳遞給某些應用, 比如消息處理
  1. 什麼是Python的list and dict comprehensions,寫一段代碼

    list and dict comprehensions 清單推導式和字典推導式

    清單推導式:

    In [1]: list1 = [x for x in range(10)]

    In [2]: list1

    Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    字典推導式:

    d = {key: value for (key, value) in iterable}

  2. Python裡面如何實作tuple和list的轉換?

    可以使用内置函數直接轉換

    list---->tuple tuple(list)

    tuple---->list list(tuple)

  3. 請寫出一段Python代碼實作删除一個list裡面的重複元素

    對清單去重有四種方法,如下代碼:

    def func1(one_list):

    ‘’’’’ 使用集合 ‘’’

    return list(set(one_list))

    def func2(one_list):

    ‘’’’’ 使用字典的方式 ‘’’

    return {}.fromkeys(one_list).keys()

    def func3(one_list):

    ‘’’’’ 使用清單推導的方式 ‘’’

    temp_list=[]

    for one in one_list:

    if one not in temp_list:

    temp_list.append(one)

    return temp_list

    def func4(one_list):

    ‘’’’’ 使用排序的方法 ‘’’

    result_list=[]

    temp_list=sorted(one_list)

    i=0

    while i<len(temp_list):

    if temp_list[i] not in result_list:

    result_list.append(temp_list[i])

    else:

    i+=1

    return result_list

    if name == ‘main’:

    AList=[1,2,3,1,2]

    print func1(AList)

    print func2(AList)

    print func3(AList)

    print func4(AList)

  4. Python裡面如何拷貝一個對象?

    Python中的指派、淺拷貝和深拷貝:

    5.1 指派:

    在python中, 對象的指派就是簡單的對象引用, 這點和C++不同, 如下所示:

    a = [1,2,"hello",['python', 'C++']]
     b = a
     在上述情況下, a和b是一樣的, 他們指向同一片記憶體, b不過是a的别名, 是引用。
     我們可以使用b is a 去判斷, 傳回True, 表明他們位址相同, 内容相同, 也可以使用id()函數來檢視兩個清單的位址是否相同。
     指派操作(包括對象作為參數、 傳回值)不會開辟新的記憶體空間, 它隻是複制了對象的引用。
     也就是說除了b這個名字之外, 沒有其他的記憶體開銷。
     修改了a, 也就影響了b;同理, 修改了b, 也就影響了a
               

    5.2 淺拷貝(shallow coopy):

    淺拷貝會建立新對象, 其内容是原對象的引用。

    淺拷貝有三種形式:切片操作、 工廠函數、 copy子產品中的copy函數

    比如上述的清單a

    切片操作: b = a[:] 或者 b = [x for x in a]

    工廠函數: b = list(a)

    copy函數: b = copy.copy(a)

    淺拷貝産生的清單b不再是清單a了, 使用is判斷可以發現他們不是同一個對象, 使用id檢視, 他們也不指向同一片記憶體空間。

    但是當我們使用id(x) for x in a 和 id(x) for x in b來檢視a和b中元素的位址時, 可以看到二者包含的元素的位址是相同的。

    在這種情況下, 清單a和b是不同的對象, 修改清單b理論上不會影響到清單a。

    但是要注意的是, 淺拷貝之是以稱之為淺拷貝, 是它僅僅隻拷貝了一層, 在清單a中有一個嵌套的list, 如果我們修改了它, 情況就不一樣了。

    比如: a[3].append(‘java’)。 檢視清單b, 會發現清單b也發生了變化, 這是因為, 我們修改了嵌套的list, 修改外層元素, 會修改它的引用, 讓它們指向别的位置, 修改嵌套清單中的元素, 清單的位址并未發生變化,指向的都是用一個位置。

    5.3 深拷貝(Deep copy):

    深拷貝隻有一種形式, copy子產品中的deepcopy()函數

    深拷貝和淺拷貝對應, 深拷貝拷貝了對象的所有元素, 包括多層嵌套的元素。 是以, 它的時間和空間開銷要高。

    同樣的對清單a, 如果使用 b = copy.deepcopy(a), 再修改清單b将不會影響到清單a, 即使嵌套的清單具有更深的層次, 也不會産生任何影響, 因為深拷貝拷貝出來的對象根本就是一個全新的對象, 不再與原來的對象有任何的關聯。

    5.4 拷貝的注意點:

    對于非容器類型, 如數字、 字元, 以及其他的“原子”類型, 沒有拷貝一說, 産生的都是原對象的引用。

    如果元組變量值包含原子類型對象, 即使采用了深拷貝, 也隻能得到淺拷貝。

  5. 寫一段使用except的函數

    try:

    f = open(“a.txt”)

    print(f.readline())

    except:

    print(“檔案不存在”)

  6. Python中pass語句的作用是什麼?

    pass語句不會執行任何操作 ,一般作為占位符或者建立占位程式

  7. 如何知道一個Python對象的類型?

    使用Python的内置函數 type(變量) 來檢視一個變量的類型

  8. 介紹一下Python中renge()函數的用法

    Python range()函數可建立一個整數清單,一般在for循環中使用

    函數文法:

    range(start, stop[, step])

    參數說明:

    • start: 計數從 start 開始。預設是從 0 開始。例如range(5)等價于range(0, 5);
    • stop: 計數到 stop 結束,但不包括 stop。例如:range(0, 5) 是[0, 1, 2, 3, 4]沒有5
    • step:步長,預設為1。例如:range(0, 5) 等價于 range(0, 5, 1)

    執行個體:

    In [6]: for x in range(10):

    …: print(x)

    …:

    1

    2

    3

    4

    5

    6

    7

    8

    9

  9. 用Python re子產品比對HTML tag的時候,<.>和<.?>有什麼差別?

    <.>這種比對稱作貪心比對 <.?>稱作非貪心比對

    第一種寫法是,盡可能多的比對,就是比對到的字元串盡量長,第二中寫法是盡可能少的比對,就是比對到的字元串盡量短。

    比如tag>tag>end,第一個會比對tag>tag>,第二個會比對,如果要比對到二個 >,就隻能自己寫了

  10. Python中如何生成随機數?

    在python中用于生成随機數的子產品是random, 在使用前需要import. 如下例子可以酌情列舉:

    • random.random(): 生成一個0-1之間的随機浮點數
    • random.uniform(a, b): 生成[a,b]之間的浮點數
    • random.randint(a, b): 生成[a,b]之間的整數
    • random.randrange(a, b, step): 在指定的集合[a,b)中, 以step為基數随機取一個數
    • random.choice(sequence): 從特定序列中随機取一個元素, 這裡的序列可以是字元串, 清單, 元組等
  11. 如何在一個function裡面設定一個全局的變量?

    如果要給全局變量在一個函數裡指派, 必須使用global語句。 globalVarName的表達式會告訴Python, VarName是一個全局變量, 這樣Python就不會在局部命名空間裡尋找這個變量了

  12. Python程式中文亂碼問題怎麼解決?

    在Python2中預設是不支援中文的,我們可以在py檔案的開頭,指定編碼為utf-8

    coding=utf8

  13. 列出Python2和Python3的差別

    性能: Py3.0運作 pystone benchmark的速度比Py2.5慢30%。 Guido認為Py3.0有極大的優化空間, 在字元串 和整型操作上可以取得很好的優化效果

    編碼: Py3.X源碼檔案預設使用utf-8編碼

    文法:

    1) 去除了<>, 全部改用!=

    2) 去除``, 全部改用repr()

    3) 關鍵詞加入as 和with, 還有True,False,None

    4) 整型除法傳回浮點數, 要得到整型結果, 請使用//

    5) 加入nonlocal語句。 使用noclocal x可以直接指派外圍( 非全局) 變量

    6) 去除print語句, 加入print()函數實作相同的功能。 同樣的還有 exec語句, 已經改為exec()函數

    7) 改變了順序操作符的行為, 例如x<y, 當x和y類型不比對時抛出TypeError而不是傳回随即的 bool值

    8) 輸入函數改變了, 删除了raw_input, 用input代替:

    2.X:guess = int(raw_input('Enter an integer : ')) # 讀取鍵盤輸入的方法

    3.X:guess = int(input('Enter an integer : '))

    9) 去除元組參數解包。 不能def(a, (b, c)):pass這樣定義函數了

    10) 新式的8進制字變量, 相應地修改了oct()函數。

    11) 增加了 2進制字面量和bin()函數

    12) 擴充的可疊代解包。 在Py3.X 裡, a, b, *rest = seq和 *rest, a = seq都是合法的, 隻要求兩點: rest是list對象和seq是可疊代的。

    13) 新的super(), 可以不再給super()傳參數,

    14) 新的metaclass文法:

    class Foo(*bases, **kwds):

    pass

    15) 支援class decorator。 用法與函數decorator一樣:

    字元和字元串:

    1) 現在字元串隻有str一種類型, 但它跟2.x版本的unicode幾乎一樣。

    2) 關于位元組串, 請參閱“資料類型”的第2條目

    資料類型:
    1) Py3.X去除了long類型, 現在隻有一種整型——int, 但它的行為就像2.X版本的long
    2) 新增了bytes類型, 對應于2.X版本的八位串, 定義一個bytes字面量的方法如下:
    str對象和bytes對象可以使用.encode() (str -> bytes) or .decode() (bytes -> str)方法互相轉化。
    3) dict的.keys()、 .items 和.values()方法傳回疊代器, 而之前的iterkeys()等函數都被廢棄。 
    同時去掉的還有 dict.has_key(), 用 in替代它吧
               

    面向對象:

    1) 引入抽象基類( Abstraact Base Classes, ABCs) 。

    2) 容器類和疊代器類被ABCs化。

    3) 疊代器的next()方法改名為__next__(), 并增加内置函數next(), 用以調用疊代器的__next__()方法

    4) 增加了@abstractmethod和 @abstractproperty兩個 decorator, 編寫抽象方法( 屬性) 更加友善。

    異常:

    1) 是以異常都從 BaseException繼承, 并删除了StardardError

    2) 去除了異常類的序列行為和.message屬性

    3) 用 raise Exception(args)代替 raise Exception, args文法

    4) 捕獲異常的文法改變, 引入了as關鍵字來辨別異常執行個體

    5) 異常鍊, 因為__context__在3.0a1版本中沒有實作

    子產品變動:

    1) 移除了cPickle子產品, 可以使用pickle子產品代替。 最終我們将會有一個透明高效的子產品。

    2) 移除了imageop子產品

    3) 移除了 audiodev, Bastion, bsddb185, exceptions, linuxaudiodev, md5, MimeWriter, mimify, popen2,

    rexec, sets, sha, stringold, strop, sunaudiodev, timing和xmllib子產品

    4) 移除了bsddb子產品(單獨釋出, 可以從http://www.jcea.es/programacion/pybsddb.htm擷取)

    5) 移除了new子產品

    6) os.tmpnam()和os.tmpfile()函數被移動到tmpfile子產品下

    7) tokenize子產品現在使用bytes工作。 主要的入口點不再是generate_tokens, 而是 tokenize.tokenize()

    其他:

    1) xrange() 改名為range(), 要想使用range()獲得一個list, 必須顯式調用:

    >>> list(range(10)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    2) bytes對象不能hash, 也不支援 b.lower()、 b.strip()和b.split()方法, 但對于後兩者可以使用 b.strip(b’ \n\t\r \f’)和b.split(b’ ‘)來達到相同目的

    3) zip()、 map()和filter()都傳回疊代器。 而apply()、 callable()、 coerce()、 execfile()、 reduce()和reload ()函數都被去除了現在可以使用hasattr()來替換 callable(). hasattr()的文法如: hasattr(string, ‘name’)

    4) string.letters和相關的.lowercase和.uppercase被去除, 請改用string.ascii_letters 等

    5) 如果x < y的不能比較, 抛出TypeError異常。 2.x版本是傳回僞随機布爾值的

    6) __getslice__系列成員被廢棄。 a[i:j]根據上下文轉換為a.getitem(slice(I, j))或 __setitem__和 __delitem__調用

    7) file類被廢棄

  14. Python的傳參是傳值還是傳址?

    Python的參數傳遞有: 位置參數、 預設參數、 可變參數、 關鍵字參數

    函數的傳值到底是值傳遞還是引用傳遞, 要分情況:

    不可變參數用值傳遞:

    像整數和字元串這樣的不可變對象, 是通過拷貝進行傳遞的,因為深拷貝拷貝出來的對象根本就是一個全新的對象,你無論如何都不可能在原處改變不可變對象

    可變參數是引用傳遞的:

    比如像清單, 字典這樣的對象是通過引用傳遞、 和C語言裡面的用指針傳遞數組很相似, 可變對象能在函數内部改變。

  15. with語句的作用,寫一段代碼?

    with open(“a.txt”,“w”) as f:

    f.write(“Hello Python”)