日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python | 深入浅出字符串

發布時間:2024/9/15 python 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python | 深入浅出字符串 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文授權轉自極客時間專欄:(Python核心技術與實戰)


(2 天倒計時!掃碼購買加微信返現 18 元)


Python的程序中充滿了字符串(string),在平常閱讀代碼時也屢見不鮮。字符串同樣是Python中很常見的一種數據類型,比如日志的打印、程序中函數的注釋、數據庫的訪問、變量的基本操作等等,都用到了字符串。


當然,我相信你本身對字符串已經有所了解。今天這節課,我主要帶你回顧一下字符串的常用操作,并對其中的一些小tricks詳細地加以解釋。


字符串基礎

什么是字符串呢?字符串是由獨立字符組成的一個序列,通常包含在單引號('')雙引號("")或者三引號之中(''' '''或""" """,兩者一樣),比如下面幾種寫法。


name?=?'jason'city?=?'beijing'text?=?"welcome?to?jike?shijian"'jason'
city?=?'beijing'
text?=?"welcome?to?jike?shijian"


這里定義了name、city和text三個變量,都是字符串類型。我們知道,Python中單引號、雙引號和三引號的字符串是一模一樣的,沒有區別,比如下面這個例子中的s1、s2、s3完全一樣。


s1?=?'hello's2?=?"hello"s3?=?"""hello"""s1?==?s2?==?s3True
s2?=?"hello"
s3?=?"""hello"""
s1?==?s2?==?s3
True


Python同時支持這三種表達方式,很重要的一個原因就是,這樣方便你在字符串中,內嵌帶引號的字符串。比如:


"I'm?a?student"


Python的三引號字符串,則主要應用于多行字符串的情境,比如函數的注釋等等。


def?calculate_similarity(item1,?item2):????"""????Calculate?similarity?between?two?items????Args:????????item1:?1st?item????????item2:?2nd?item????Returns:??????similarity?score?between?item1?and?item2????"""
????"""
????Calculate?similarity?between?two?items
????Args:
????????item1:?1st?item
????????item2:?2nd?item
????Returns:
??????similarity?score?between?item1?and?item2
????"""


同時,Python也支持轉義字符。所謂的轉義字符,就是用反斜杠開頭的字符串,來表示一些特定意義的字符。我把常見的的轉義字符,總結成了下面這張表格。


? ? ?

為了方便你理解,我舉一個例子來說明。


s?=?'a\nb\tc'print(s)ab????c
print(s)
a
b????c


這段代碼中的'\n',表示一個字符——換行符;'\t'也表示一個字符——橫向制表符。所以,最后打印出來的輸出,就是字符a,換行,字符b,然后制表符,最后打印字符c。不過要注意,雖然最后打印的輸出橫跨了兩行,但是整個字符串s仍然只有5個元素。


len(s)5
5


在轉義字符的應用中,最常見的就是換行符'\n'的使用。比如文件讀取,如果我們一行行地讀取,那么每一行字符串的末尾,都會包含換行符'\n'。而最后做數據處理時,我們往往會丟掉每一行的換行符。


字符串的常用操作

講完了字符串的基本原理,下面我們一起來看看字符串的常用操作。你可以把字符串想象成一個由單個字符組成的數組,所以,Python的字符串同樣支持索引,切片和遍歷等等操作。


name?=?'jason'name[0]'j'name[1:3]'as''jason'
name[0]
'j'
name[1:3]
'as'


和其他數據結構,如列表、元組一樣,字符串的索引同樣從0開始,index=0表示第一個元素(字符),[index:index+2]則表示第index個元素到index+1個元素組成的子字符串。


遍歷字符串同樣很簡單,相當于遍歷字符串中的每個字符。


for?char?in?name:????print(char)???jasonchar?in?name:
????print(char)???
j
a
s
o
n


特別要注意,Python的字符串是不可變的(immutable)。因此,用下面的操作,來改變一個字符串內部的字符是錯誤的,不允許的。


s?=?'hello's[0]?=?'H'Traceback?(most?recent?call?last):??File?"<stdin>",?line?1,?in?<module>TypeError:?'str'?object?does?not?support?item?assignment
Traceback?(most?recent?call?last):
??File?"<stdin>",?line?1,?in?<module>
TypeError:?'str'?object?does?not?support?item?assignment


Python中字符串的改變,通常只能通過創建新的字符串來完成。比如上述例子中,想把'hello'的第一個字符'h',改為大寫的'H',我們可以采用下面的做法:


s?=?'H'?+?s[1:]s?=?s.replace('h',?'H')'H'?+?s[1:]
s?=?s.replace('h',?'H')


  • 第一種方法,是直接用大寫的'H',通過加號'+'操作符,與原字符串切片操作的子字符串拼接而成新的字符串。


  • 第二種方法,是直接掃描原字符串,把小寫的'h'替換成大寫的'H',得到新的字符串。


你可能了解到,在其他語言中,如Java,有可變的字符串類型,比如StringBuilder,每次添加、改變或刪除字符(串),無需創建新的字符串,時間復雜度僅為O(1)。這樣就大大提高了程序的運行效率。


但可惜的是,Python中并沒有相關的數據類型,我們還是得老老實實創建新的字符串。因此,每次想要改變字符串,往往需要O(n)的時間復雜度,其中,n為新字符串的長度。


你可能注意到了,上述例子的說明中,我用的是“往往”、“通常”這樣的字眼,并沒有說“一定”。這是為什么呢?顯然,隨著版本的更新,Python也越來越聰明,性能優化得越來越好了。


這里,我著重講解一下,使用加法操作符'+='的字符串拼接方法。因為它是一個例外,打破了字符串不可變的特性。


操作方法如下所示:


str1?+=?str2??#?表示str1?=?str1?+?str2


我們來看下面這個例子:


s?=?''for?n?in?range(0,?100000):????s?+=?str(n)
for?n?in?range(0,?100000):
????s?+
=?str(n)


你覺得這個例子的時間復雜度是多少呢?


每次循環,似乎都得創建一個新的字符串;而每次創建一個新的字符串,都需要O(n)的時間復雜度。因此,總的時間復雜度就為O(1) + O(2) + ... + O(n) = O(n^2)。這樣到底對不對呢?


乍一看,這樣分析確實很有道理,但是必須說明,這個結論只適用于老版本的Python了。自從Python2.5開始,每次處理字符串的拼接操作時(str1 += str2),Python首先會檢測str1還有沒有其他的引用。如果沒有的話,就會嘗試原地擴充字符串buffer的大小,而不是重新分配一塊內存來創建新的字符串并拷貝。這樣的話,上述例子中的時間復雜度就僅為O(n)了。


因此,以后你在寫程序遇到字符串拼接時,如果使用'+='更方便,就放心地去用吧,不用過分擔心效率問題了。


另外,對于字符串拼接問題,除了使用加法操作符,我們還可以使用字符串內置的join函數。string.join(iterable),表示把每個元素都按照指定的格式連接起來。


l?=?[]for?n?in?range(0,?100000):????l.append(str(n))l?=?'?'.join(l)?for?n?in?range(0,?100000):
????l.append(str(n))
l?
=?'?'.join(l)?


由于列表的append操作是O(1)復雜度,字符串同理。因此,這個含有for循環例子的時間復雜度為n*O(1)=O(n)。


接下來,我們看一下字符串的分割函數split()。string.split(separator),表示把字符串按照separator分割成子字符串,并返回一個分割后子字符串組合的列表。它常常應用于對數據的解析處理,比如我們讀取了某個文件的路徑,想要調用數據庫的API,去讀取對應的數據,我們通常會寫成下面這樣:


def?query_data(namespace,?table):????"""????given?namespace?and?table,?query?database?to?get?corresponding????data?????????????"""path?=?'hive://ads/training_table'namespace?=?path.split('//')[1].split('/')[0]?#?返回'ads'table?=?path.split('//')[1].split('/')[1]?#?返回?'training_table'data?=?query_data(namespace,?table)?
????"""
????given?namespace?and?table,?query?database?to?get?corresponding
????data?????????
????"""



path?=?'hive://ads/training_table'
namespace?=?path.split('//')[1].split('/')[0]?#?返回'ads'
table?=?path.split('//')[1].split('/')[1]?#?返回?'training_table'
data?=?query_data(namespace,?table)?


此外,常見的函數還有:

  • string.strip(str),表示去掉首尾的str字符串;

  • string.lstrip(str),表示只去掉開頭的str字符串;

  • string.rstrip(str),表示只去掉尾部的str字符串。


這些在數據的解析處理中同樣很常見。比如很多時候,從文件讀進來的字符串中,開頭和結尾都含有空字符,我們需要去掉它們,就可以用strip()函數:


s?=?'?my?name?is?jason?'s.strip()'my?name?is?jason''?my?name?is?jason?'
s.strip()
'my?name?is?jason'


當然,Python中字符串還有很多常用操作,比如,string.find(sub, start, end),表示從start到end查找字符串中子字符串sub的位置等等。這里,我只強調了最常用并且容易出錯的幾個函數,其他內容你可以自行查找相應的文檔、范例加以了解,我就不一一贅述了。


字符串的格式化

最后,我們一起來看看字符串的格式化。什么是字符串的格式化呢?


通常,我們使用一個字符串作為模板,模板中會有格式符。這些格式符為后續真實值預留位置,以呈現出真實值應該呈現的格式。字符串的格式化,通常會用在程序的輸出、logging等場景。


舉一個常見的例子。比如我們有一個任務,給定一個用戶的userid,要去數據庫中查詢該用戶的一些信息,并返回。而如果數據庫中沒有此人的信息,我們通常會記錄下來,這樣有利于往后的日志分析,或者是線上bug的調試等等。


我們通常會用下面的方法來表示:


print('no?data?available?for?person?with?id:?{},?name:?{}'.format(id,?name))'no?data?available?for?person?with?id:?{},?name:?{}'.format(id,?name))


其中的string.format(),就是所謂的格式化函數;而大括號{}就是所謂的格式符,用來為后面的真實值——變量name預留位置。如果id = '123'、name='jason',那么輸出便是:


'no?data?available?for?person?with?id:?123,?name:?jason'


這樣看來,是不是非常簡單呢?


不過要注意,string.format()是最新的字符串格式函數與規范。自然,我們還有其他的表示方法,比如在Python之前版本中,字符串格式化通常用%來表示,那么上述的例子,就可以寫成下面這樣:


print('no?data?available?for?person?with?id:?%s,?name:?%s'?%?(id,?name))'no?data?available?for?person?with?id:?%s,?name:?%s'?%?(id,?name))


其中%s表示字符串型,%d表示整型等等,這些屬于常識,你應該都了解。


當然,現在你寫程序時,我還是推薦使用format函數,畢竟這是最新規范,也是官方文檔推薦的規范。


也許有人會問,為什么非要使用格式化函數,上述例子用字符串的拼接不也能完成嗎?沒錯,在很多情況下,字符串拼接確實能滿足格式化函數的需求。但是使用格式化函數,更加清晰、易讀,并且更加規范,不易出錯。


總結

這節課,我們主要學習了Python字符串的一些基本知識和常用操作,并且結合具體的例子與場景加以說明,特別需要注意下面幾點。


  • Python中字符串使用單引號、雙引號或三引號表示,三者意義相同,并沒有什么區別。其中,三引號的字符串通常用在多行字符串的場景。

  • Python中字符串是不可變的(前面所講的新版本Python中拼接操作'+='是個例外)。因此,隨意改變字符串中字符的值,是不被允許的。

  • Python新版本(2.5+)中,字符串的拼接變得比以前高效了許多,你可以放心使用。

  • Python中字符串的格式化(string.format)常常用在輸出、日志的記錄等場景。


思考題

最后,給你留一道思考題。在新版本的Python(2.5+)中,下面的兩個字符串拼接操作,你覺得哪個更優呢?歡迎留言和我分享你的觀點,也歡迎你把這篇文章分享給你的同事、朋友。


s?=?''for?n?in?range(0,?100000):????s?+=?str(n)l?=?[]for?n?in?range(0,?100000):????l.append(str(n))s?=?'?'.join(l)
for?n?in?range(0,?100000):
????s?+
=?str(n)


l?=?[]
for?n?in?range(0,?100000):
????l.append(str(n))

s?
=?'?'.join(l)


(2 天倒計時!掃碼購買加微信返現 18 元)

總結

以上是生活随笔為你收集整理的Python | 深入浅出字符串的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。