發現問題
最近在面試的時候遇到一個題目,選擇用JavaScript或Python實現字串反轉,我選擇了Python,然後寫出了程式碼(錯誤的):
#!/usr/bin/env python #-*-coding:utf-8-*- __author__ = 'ZhangHe' def reverse(s): l = 0 r = len(s) - 1 while l < r: s[l],s[r] = s[r],s[l] l += 1 r -= 1 return s
接著面試官問了兩個問題:
(1)可以這樣修改字串的值嗎? 【我回答的,可以】【回答錯誤】
(2)傳入的參數是位址?還是副本? 【我回答的,傳值。數字,字串,元組傳值(immutable);list和dict傳引用(mutable);】【回答傳值,可以直接修改】【回答錯誤,正確的是傳值,immutable】
思考如下
雖然常常使用字串,但是還真沒有研究過這個問題,於是上網搜了一下資料:
Python中的字串是不可變類型,就是說改變一個字串的元素需要新建一個新的字串。
字串是由獨立的字元組成的,也是一種序列,序列的通用操作方法也適用於字串。
例如:
以切片操作順序存取子串;
以len()求字串的長度等;
透過in或not in運算子判斷字串中是否存在某個字元。
Python裡面沒有字元這個類型,而是用長度為1 的字串來表示這個概念,當然,這其實也是一個子字串。
訪問字串舉例:
1 aString = 'Hello World!' 2 print(aString[0]) 3 print(aString[1:5]) 4 print(aString[6:])
輸出:
H ello World!
那麼如何改變一個字串呢?
可以透過給一個變數賦值(或重賦值)的方式「更新」一個已有的字串。新的值可能與原有值差不多,也可能跟原有串完全不同。
例如:
1 aString = 'Hello World!' 2 aString = aString[:6] + 'Python!' 3 print(aString) 4 aString = 'different string altogether' 5 print(aString)
輸出:
Hello Python! different string altogether
那麼如何刪除一個字元或字串呢?
再重複一遍,字符串是不可變的,所以不能僅僅刪除一個字符串裡的某個字符,你能做的是清空一個空字符串,或者是把剔除了不需要的部分後的字符串組合起來形成一個新串。
假設您想要從“Hello World!”裡面刪除小寫的“l”,那麼您需要這樣做:
1 aString = 'Hello World!' 2 aString = aString[:3] + aString[4:] 3 print(aString)
輸出:
Helo World!
透過賦一個空字串或使用del 語句來清空或刪除一個字串。不過,在大部分應用程式裡,沒有必要明確的刪除字串。定義這個字串的程式碼最終會結束,那時Python 會自動釋放這些字串。
所以,我寫的反轉字串程式碼是有問題的,正確的程式碼應該是:
#!/usr/bin/env python #-*-coding:utf-8-*- __author__ = 'ZhangHe' def reverse(s): t = '' r = len(s) - 1 while r>=0: t = t + s[r] r -= 1 return t s = 'abcd' print reverse(s)
那麼傳入的形參s和實參s到底是不是同一個對象呢?可以用id函數來驗證,先來看id函數的官方解釋。
也就是說,id(obj)
函數返回對象obj在其生命週期內位於內存中的地址,id函數的參數類型是一個對象(Python中一切對象,變量中存放的是對象的引用)
我們可以用下邊的程式碼來驗證:
#!/usr/bin/env python #-*-coding:utf-8-*- __author__ = 'ZhangHe' def reverse(s): print id(s) t = '' r = len(s) - 1 while r>=0: t = t + s[r] r -= 1 return t s = 'abasdfasdfcdabasdfasdfcd' print id(s) print reverse(s)
輸出:
38264224 38264224 dcfdsafdsabadcfdsafdsaba
可以看出傳入的參數其實是字串物件的位址,如果把參數換成list或dict,那麼輸出的id還是一樣的,所以所,Python中傳參的方式都是傳入物件的位址,只不過數字,字串和tuple是不可直接修改,而list和dict是可以直接修改。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或工作能帶來一定的幫助,如果有疑問大家可以留言交流。