你真的知道 Python 字符串怎麼用嗎?

2021-02-19 CSDN

作者 | 豌豆花下貓
責編 | 郭芮

Python 中字符串是由 Uniocde 編碼的字符組成的不可變序列,它具備與其它序列共有的一些操作,例如判斷元素是否存在、拼接序列、切片操作、求長度、求最值、求元素的索引位置及出現次數等等。

除此之外,它還有很多特有的操作,值得我們時常溫故學習,所以,今天我就跟大家繼續聊聊字符串。

本文主要介紹 Python 字符串特有的操作方法,比如它的拼接、拆分、替換、查找及字符判斷等使用方法,辨析了一些可能的誤區。最後,還做了兩個擴展思考:為什麼 Python 字符串不具備列表類型的某些操作呢,為什麼它不具備 Java 字符串的一些操作呢?兩相比較,希望能幫助你透徹地理解——Python 的字符串到底怎麼用?

拼接字符串

字符串的拼接操作最常用,七種拼接方式從實現原理上劃分為三類,即格式化類(%佔位符、format()、template)、拼接類(+操作符、類元祖方式、join())與插值類(f-string),在使用上,我有如下建議:

當要處理字符串列表等序列結構時,採用join()方式;

拼接長度不超過20時,選用+號操作符方式;

長度超過20的情況,高版本選用f-string,低版本時看情況使用format()或join()方式。

不敢說字符串就只有這七種拼接方式,但應該說它們是最常見的了。有小夥伴說,我寫漏了一種,即字符串乘法,可以重複拼接自身。沒錯,從結果上看,這是第八種拼接方式,視為補充吧。

關於字符串拼接,還得補充一個建議,即在複雜場景下,儘量避免使用以上幾類原生方法,而應該使用外置的強大的處理庫。

比如在拼接 SQL 語句的時候,經常要根據不同的條件分支,來組裝不同的查詢語句,而且還得插入不同的變量值,所以當面臨這種複雜的場景時,傳統拼接方式只會加劇代碼的複雜度、降低可讀性和維護性。使用SQLAlchemy模塊,將有效解決這個問題。

拆分字符串

在字符串的幾種拼接方法中,join() 方法可以將列表中的字符串元素,拼接成一個長的字符串,與此相反,split() 方法可以將長字符串拆分成一個列表。前面已說過,字符串是不可變序列,所以字符串拆分過程是在拷貝的字符串上進行,並不會改變原有字符串。

split() 方法可接收兩個參數,第一個參數是分隔符,即用來分隔字符串的字符,默認是所有的空字符,包括空格、換行(\n)、制表符(\t)等。拆分過程會消耗分隔符,所以拆分結果中不包含分隔符。

s = 'Hello world'
l = '''Hi there , my name is     Python貓
Do you like me ?
'''

# 不傳參數時,默認分隔符為所有空字符
s.split() >>> ['Hello', 'world']
s.split(' ') >>> ['Hello', 'world']
s.split('  ') >>> ['Hello world'] # 不存在兩個空格符
s.split('world') >>> ['Hello', '']

# 空字符包括空格、多個空格、換行符等
l.split() >>> ['Hi', 'there', ',', 'my', 'name', 'is', 'Python貓', 'Do', 'you', 'like', 'me', '?']

split() 方法的第二個參數是一個數字,默認是預設,預設時全分隔,也可以用 maxsplit 來指定拆分次數。

# 按位置傳參
l.split(' ',3)
>>> ['Hi', 'there', ',', 'my name is     Python 貓\nDo you like me ?\n']

# 指定傳參
l.split(maxsplit=3)
>>> ['Hi', 'there', ',', 'my name is     Python 貓\nDo you like me ?\n']

# 錯誤用法
l.split(3)

TypeError  Traceback (most recent call last)
<ipython-input-42-6c16d1a50bca> in <module>()
----> 1 l.split(3)
TypeError: must be str or None, not int

split() 方法是從左往右遍歷,與之相對,rsplit() 方法是從右往左遍歷,比較少用,但是會有奇效。

拆分字符串還有一種方法,即 splitlines() ,這個方法會按行拆分字符串,它接收一個參數 True 或 False,分別決定換行符是否會被保留,默認值 False,即不保留換行符。

# 默認不保留換行符
'ab c\n\nde fg\rkl\r\n'.splitlines()
>>> ['ab c', '', 'de fg', 'kl']

'ab c\n\nde fg\rkl\r\n'.splitlines(True)
>>> ['ab c\n', '\n', 'de fg\r', 'kl\r\n']

替換字符串

替換字符串包括如下場景:大小寫替換、特定符號替換、自定義片段替換……

再次說明,字符串是不可變對象,以下操作並不會改變原有字符串。

以上這些方法都很明了,使用也簡單,建議你親自試驗一下。這裡只說說 strip() 方法,它比較常用,可以去除字符串前後的空格,不僅如此,它還可以刪除首末位置的指定的字符。

s = '******Hello world******'
s.strip('*') >>> 'Hello world'

查找字符串

查找字符串中是否包含某些內容,這是挺常用的操作。Python 中有多種實現方式,例如內置的 find() 方法,但是這個方法並不常用,因為它僅僅告訴你所查找內容的索引位置,而在通常情況下,這個位置並不是我們的目的。

find() 方法與 index() 方法的效果一樣,它們的最大的區別只在於,找不到內容時的返回值不同,一個返回 -1,一個拋出異常 :

s = 'Hello world'

s.find('cat') >>>  -1

s.index('cat') 
>>> ValueError  Traceback (most recent call last)
<ipython-input-55-442007c50b6f> in <module>()
----> 1 s.index('cat')

ValueError: substring not found

以上兩個方法,只能用來滿足最簡單的查找需求。

在實戰中,我們常常要查找特定模式的內容,例如某種格式的日期字符串,這就得藉助更強大的查找工具了。正則表達式和 re 模塊就是這樣的工具,正則表達式用來定製匹配規則,re 模塊則提供了 match() 、find() 及 findall() 等方法,它們組合起來,可以實現複雜的查找功能。限於篇幅,今後再對這兩大工具做詳細介紹,這裡有一個簡單的例子:

import re
datepat = re.compile(r'\d+/\d+/\d+')
text = 'Today is 11/21/2018. Tomorrow is 11/22/2018.'
datepat.findall(text)
>>> ['11/21/2018', '11/22/2018']

字符判斷

判斷字符串是否(只)包含某些字符內容,這類使用場景也很常見,例如在網站註冊時,要求用戶名只能包含英文字母和數字,那麼,當校驗輸入內容時,就需要判斷它是否只包含這些字符。其它常用的判斷操作,詳列如下:

字符串不可以做的事

上文內容都是 Python 字符串特有的操作方法,相信讀完之後,你更清楚知道 Python 能夠做什麼了。

但是,這還不足以回答本文標題的問題——你真的知道 Python 的字符串怎麼用嗎?這些特有的操作方法,再加上之前文章提到的序列共有的操作、字符串讀寫文件、字符串列印、字符串Intern機制等等內容,才差不多能夠回答這個問題。

儘管如此,為了體現嚴謹性,我試著再聊聊「Python 字符串不可以做的事」,從相反的維度來補充回答這個問題。下面是開拓思維,進行頭腦風暴的時刻:

(1)受限的序列

與典型的序列類型相比,字符串不具備列表的如下操作:append()、clear()、copy()、insert()、pop()、remove(),等等。這是為什麼呢?

有幾個很好理解,即append()、insert()、pop() 和 remove()都是對單個元素的操作,但是字符串中的單個元素就是單個字符,通常沒有任何意義,我們也不會頻繁對其做增刪操作,所以字符串沒有這幾個方法也算合理。

列表的 clear() 方法會清空列表,用來節省內存空間,效果等於anylist[:] = [],但是,奇怪的是,Python 並不支持清空/刪除操作。

首先,字符串沒有 clear() 方法,其次,它是不可變對象,不支持這種賦值操作anystr[:] = '',也不支持del anystr[:]操作:

s = 'Hello world'

s[:] = ''
>>> 報錯:TypeError: 'str' object does not support item assignment

del s[:]
>>> 報錯:TypeError: 'str' object does not support item deletion

當然,你也別想通過del s來刪除字符串,因為變量名 s 只是字符串對象的引用(挖坑,以後寫寫這個話題),只是一個標籤,刪除標籤並不會直接導致對象實體的消亡。

如此看來,想要手動清空/刪除 Python 字符串,似乎是無解。

最後還有一個 copy() 方法,這就是拷貝嘛,可是字符串也沒有這個方法。為什麼呢?難道拷貝字符串的場景不多麼?在這點上,我也沒想出個所以然來,擱置疑問。

通過以上幾個常用列表操作的比較,我們可以看出字符串這種序列是挺受限的。列表可以看成多節車廂連結成的火車,而字符串感覺就只像多個座椅聯排成的長車廂,真是同源不同相啊。

(2)比就比,誰怕誰

接下來,又到了 Python 字符串與 Java 字符串 PK 的時刻。在對象定義的角度上,Python 的確更勝一籌,這次看看會比出個啥結果吧。

Java 中有比較字符串的方法,即 compareTo() 方法與 equals() 方法,前一個方法逐一比較兩個字符串的字符編碼,返回一個整型的差值,後一個方法在整體上比較兩個字符串的內容是否相等。

Python 字符串沒有這兩個單獨的方法,但要實現類似的功能卻很簡便。先看例子:

myName = "Python貓"
cmpName = "world"
newName = myName

# 直接用比較符號進行compare
myName > cmpName  
>>> False
myName == newName
>>> True
cmpName != newName
>>> True

# 比較是否同一對象
myName is cmpName
>>> False
myName is newName
>>> True

上例中,如果把賦值的字符串換成列表或者其它對象,這些比較操作也是可以進行的。也就是說,作比較的能力是 Python 公民們的一項基本能力,並不會因為你是字符串就給你設限,或者給你開特權。

與此類似,Python 公民們自帶求自身長度的能力,len() 方法是內置方法,可以直接傳入任意序列參數,求解長度。Java 中則要求不同的序列對象,只能調用各自的 length() 方法。說個形象的比喻,Python 中共用一把秤,三教九流之輩都能拿它稱重,而Java 中有多把秤,你稱你的,我稱我的,大家「井水不犯河水」。

Python 中曾經有 cmp() 方法和__cmp__()魔術方法,但官方嫌棄它們雞肋,所以在Python 3 中移除掉了。雖然在 operator 模塊中還為它留下了一脈香火,但保不定哪天就會徹底廢棄。

import operator
operator.eq('hello', 'name')
>>> False
operator.eq('hello', 'hello')
>>> True
operator.gt('hello', 'name')
>>> False
operator.lt('hello', 'name')
>>> True

(3)牆上的門

在 Java 中,字符串還有一個強大的 valueOf() 方法,它可以接收多種類型的參數,如boolean、char、char數組、double、float、int等等,然後返回這些參數的字符串類型。 例如,要把 int 轉為字符串,可以用 String.valueOf(anynum) 。

Python 字符串依然沒有這個單獨的方法,但要實現相同的功能卻很簡便。對Python來說,不同的數據類型轉換成字符串,那是小菜一碟,例如:

str(123) >>> '123'
str(True) >>> 'True'
str(1.22) >>> '1.22'
str([1,2]) >>> '[1, 2]'
str({'name':'python', 'sex':'male'})
>>> "{'name': 'python', 'sex': 'male'}"

而從字符串轉換為其它類型也不難,例如,int('123') 即可由字符串'123'得到數字 123。對比 Java,這個操作要寫成 Integer.parseInt('123')。

在Java 的不同數據類型之間,那道分隔之牆矗立得很高,仿佛需要藉助一座更高的吊橋才能溝通兩邊,而在靈活的 Python 裡,你可以很方便地打開牆上的那扇門,來往穿越。

小結一下,跟 Java 相比,Python 字符串確實沒有幾項方法,但是事出有因,它們的天賦能力可不弱,所有這些操作都能簡明地實現。一方面,Python 字符串做不到某些事,但是另一方面,Python 可以出色地做成這些事,孰優孰劣,高下立判。

總結

寫文章貴在善始善終,現在給大家總結一下:

本文主要介紹 Python 字符串特有的操作方法,比如它的拼接、拆分、替換、查找及字符判斷等使用方法,從正向回答,Python 字符串能做什麼?最後,我們還從反向來回答了 Python 字符串不能做什麼?有些不能做,實際上是 不為,是為了在其它地方更好地作為,歸根到底,應該有的功能,Python 字符串全都有了。

本文中還將 Python 與 Java 做了比較,有幾項小小的差異,背後反映的其實是,兩套語言系統在世界觀上的差異。古人云,以銅為鏡,可以正衣冠。那麼,在程式語言的世界裡,以另一種語言為鏡,也更能看清這種語言的面貌。希望這種跨語言的思維碰撞,能為你擦出智慧的火花。

作者:豌豆花下貓,某985高校畢業生, 兼具極客思維與人文情懷。公眾號Python貓,專注Python技術、數據科學和深度學習,力圖創造一個有趣又有用的學習分享平臺。

聲明:本文為作者投稿,版權歸作者個人所有。

 熱 文 推 薦 

☞ 力壓今日頭條成 App Store 榜第一,個稅 App 驚爆 62 例木馬病毒!

☞ 雷軍:執掌金山純屬意外

☞ 程式設計師如何玩轉彙編指令?

☞ 無業務不技術:那些誓用區塊鏈重塑的行業,發展怎麼樣了?

☞ 下一次 IT 變革:邊緣計算(Edge computing)

☞ 12306 脫庫 410 萬用戶數據究竟從何洩漏?

☞ 年度重磅:《AI聚變:2018年優秀AI應用案例TOP 20》正式發布

☞ 老程式設計師肺腑忠告:千萬別一輩子靠技術生存!

print_r('點個好看吧!');
var_dump('點個好看吧!');
NSLog(@"點個好看吧!");
System.out.println("點個好看吧!");
console.log("點個好看吧!");
print("點個好看吧!");
printf("點個好看吧!\n");
cout << "點個好看吧!" << endl;
Console.WriteLine("點個好看吧!");
fmt.Println("點個好看吧!");
Response.Write("點個好看吧!");
alert("點個好看吧!")
echo "點個好看吧!"

點擊「閱讀原文」,打開 CSDN App 閱讀更貼心!

相關焦點

  • Python 格式化字符串的最佳姿勢
    Python 處理數據和文本的同學一定經常要和字符串格式化打交道,少不了要打一堆 %。這當然不是因為被虐習慣了,而是我發現相比用 % 進行字符串格式化,有更好用的方法,今天就給大家分享一下。在進入正題之前,還是應該來回顧一下之前我們是怎麼格式化字符串的。
  • Python正則表達式:特殊符號和字符
    簡而言之,正則表達式(簡稱regex)是由一些字符和特殊符號組成的字符串,它描述了模式的重複或者表達多個字符。python通過標準庫中的re模塊來支持正則表達式。下圖是最常見的特殊符號和字符,也稱元字符,正是它給予正則表達式強大的功能和靈活性。
  • 用Python求最長子串長度快速版
    哈嘍大家好,周二也是令人愉快的一天啊,今天天氣不錯,坐在窗戶旁邊邊曬太陽邊寫文章,再泡杯熱茶,真是舒服美好,廢話不多說,今天說一下Python求最長子串長度,希望對大家有作用,raksmart伺服器。給定一個字符串,求它最長的回文子串長度,例如輸入字符串'35534321',它的最長回文子串是'3553',所以返回4。
  • Python中如何分割、合併字符串
    第七十四節:分割、合併字符串字符串可以通過分割操作,劃分成一個個小個體;也可以用過合併操作,重新組成一個完整的字符串。它的格式是下面這樣的:strlist = string.split(sep,maxsplit)上面的strlist代表了分割後的字符列表;字符串string後用一個英文半角句號「.」連接split函數;小括號「()」
  • Python中去除字符串首尾空格、特殊字符和指定子字符串的方法
    去除字符串首尾空格和特殊字符從上面的實例可以看出,在Python的IDLE中,定義好一個字符串後,直接使用字符串變量名回車,就會輸出包含特殊字符的字符串;使用print()函數輸出字符串時去除字符串首尾指定的子字符串從strip()方法中,又延伸出了去除字符串開頭和結尾位置空格、特殊字符和指定子字符串的方法。
  • 深入剖析go中字符串的編碼問題——特殊字符的string怎麼轉byte?
    string怎麼轉成[]byte?」。接下來,我們通過下面的代碼來驗證字符和unicode和整型的等價關係:根據上面的代碼輸出的3個true可以知道,字符和unicode和整形是等價,並且整型也能轉回字符的表現形式。
  • 騰訊大佬的 Python 編碼規範
    解釋器聲明編碼格式聲明模塊注釋或文檔字符串模塊導入常量和全局變量聲明頂級定義(函數或類定義)執行代碼編碼格式聲明通常,編碼格式聲明是必需的。如果 python 源碼文件沒有聲明編碼格式,python 解釋器會默認使用 ASCII 編碼,一旦源碼文件包含非ASCII編碼的字符,python 解釋器就會報錯。以 UTF-8 為例,以下兩種編碼格式聲明都是合乎規則的。我一直 UTF-8 編碼格式,喜歡使用第一種聲明方式。Windows 平臺上,編碼格式聲明必須位於 python 文件的第一行。
  • 《第2章 Python 語法基礎》2.3.2 字符串!
    《高中信息技術 Python編程》 教學案 《第2章 Python 語法基礎》2.3.2 字符串!瀏覽器版本過低,暫不支持視頻播放2.3.2、字符串:字符串是連續的字符序列,可以是計算機所能表示的一切字符的集合,屬於不可變序列。
  • Python3的字符串類型(瘋狂Python)
    先看一下本篇文章要講的內容目錄:4.2 字符串入門String4.2.1 repr和字符串4.2.2 input和raw_input4.2.3 長字符串4.2.4 bytes4.2.5 字符串格式化4.2.6 Python自帶兩個幫助函數4.2.7 刪除多餘空白4.2.8 字符串的查找,替換4.2.9 字符串的分割,連接方法4.2.9 運算符-4.2
  • python爬蟲 - 字符串
    python字符串Python中的字符串可以使用單引號、雙引號和三引號(三個單引號或三個雙引號,可以換行的)括起來,使用反斜槓 \ 轉義特殊字符Python3源碼文件默認以UTF-8編碼,所有字符串都是unicode字符串支持字符串拼接、截取等多種運算
  • 學習Python正則表達式
    正則表達式正則表達式是一個具有特殊字符的序列。它有助於檢查字符串中的每個字符,看它是否與某個模式匹配:哪些字符在什麼位置出現了多少次。result = re.findall(r』\d』, text)這將返回所有數字,但每個元素只有一個數字:['1', '0', '0', '1', '1', '1', '1', '2', '3', '4', '5', '6', '7']r-python原始字符串這裡,r表示python
  • 慢步學習二級python,字符串類型的操作:操作符,函數和方法
    繼續學習二級python考試的大綱內容:4.字符串類型的操作:字符串操作符,處理函數和處理方法學習字符串類型數據的操作是學習python的基礎。得到字符串「愛你」。逗號作為分隔符,第一個指令產生的是一個元組類型數據(以後再考慮,這裡不細究),該元組包含兩個字符串「我」和「愛你」在第2個指令中,把逗號變成空格,這裡的空格和+一樣,把「我」、「愛」、「你」三個單獨的字符串連接在一起了。後面的*,跟乘法類似,*2,就是對應字符串重複2次。「love」字符串重複2次,再由+與前面「我愛你」連接。
  • C語言|字符串數組的初始化
    用字符串初始化2. 用單個字符初始化在這裡我們可以看到,存儲「hello」的字符串數組的大小應該至少為6的,但這裡我們發現把數組的大小設為5,程序也可以正常運行,如下圖所示。再小了就會報錯了但是,在用第一種方法,即直接用字符串賦值的時候卻要嚴格遵守字符串數組的大小規則此時程序報錯,有知道這是為什麼的朋友可以留言或者私信我在插入了』\0』之後,字符串就結束了也可以在其中插入回車符來實現換行的效果
  • 魔獸世界:六串神秘「字符」,玩了多年魔獸,還是沒搞懂啥意思
    這些「字符」普通玩家根本不知道什麼意思,可能只有暴雪知道這些字符有什麼用意,沒錯今天我們要說的就是這些神秘的字符,話不多說,開始我們今天的BB!第二串神秘字符:介紹面板上的神秘「亂碼」如果你玩過諾莫瑞根這個副本,肯定看到過上面這個一個介紹面板,這個面板上,有一串非常神秘的字符(這串字符,是用0和1排列的),第一次見到這樣的字符的時候,還一度認為是我的電腦出了問題
  • 單片機上運行Python-MicroPython(三)
    該進程會在後臺自動運行,你也可以直接顯式地使用gc.collect()對該過程進行調用。如果感覺上述論述稍微有一點點複雜,只需要記住:周期性地進行如下調用即可。其多存在於gc模塊和micropython模塊。可將下面的示例代碼粘貼到REPL中運行查看效果。
  • 利用python免殺cs shellcode
    0x03 為什麼使用pythonpython語言入門門檻低,上手快,且兩三年前就出現了這種免殺方式,但是很多人說網上公開的代碼已經不免殺了。事實真的如此嗎?你有沒有靜下心來code過,是否去了解過相關的原理,是否通過學習到的原理去思維發散過,是否通過code去fuzz過?
  • Python輸出數據print,獲取輸入數據input,基礎入門
    python的輸入和輸出一、print輸出print 默認輸出是換行的,如果要實現不換行需要在變量末尾加上 end=""如:print把內容輸出到文件二、input輸入print是輸出,input接收鍵盤的輸入input()函數,是python的內置函數,接收任意數據類型的輸入,將所有輸入的數據,定義為字符串來進行處理
  • Python 初學者進階的九大技能
    右側是摺疊了if/else語句的ATOM另一種辦法是將你的代碼通過 www.pythontutor.com可視化,就可以逐行查看代碼運行的方式了。使用pythontutors執行代碼4.使用字符串:這部分內容其實與字符串不完全相關,與挖掘Python優雅的庫有更大關係。我們很早就在Python中學過,字符串也可以看作是一串字符。你也可以使用索引訪問字符串中的字符。
  • 回文字符串問題分析
    回文字符串,是指正讀和倒讀的結果一樣的字符串,從結構上來看,兩側的字符呈中心對稱。在漢語中,有很多有趣的迴文詩詞,回文對聯熟語,比如「響水池中池水響,黃金谷裡谷金黃」、「霧鎖山頭山鎖霧,天連水尾水連天」等。
  • python 中的運算比較符 is 與 ==
    is 什麼情況下用 == 呢,所以今天我們就來簡單認識一下這兩個比較符吧。的緩存機制在認識 is 運算符之前我們先來簡單了解一下python的緩存機制整數對象python中,對於(-5 ... 256)之間的整數,系統已經提前分配好了內存地址,所以在使用到這期間的整數對象時,會直接讀取內存池中對應的內存地址,不會創建新的對象。