Hi, 大家好。我是茶桁。
前幾節課中我們學習了函數,那麼這節課開始,我們花幾節課返過頭來詳細的學習一下Python内的資料類型。第一節課,讓我們先從字元串開始:
- 回顧字元串的定義方式
- 了解轉義字元
- 字元串格式化的方法
- 字元串相關函數
字元串的定義方式
- 單引号定義字元串 ‘ ’
- 雙引号定義字元串“ ”
- 三引号定義字元串‘’‘内容’‘’或者“”“内容”“”
- 字元串定義時,引号可以互相嵌套
轉義字元
一個普通的字元出現在轉義符\的後面時,實作了另外一種意義。
- \ 轉義符,續行符。
作為轉義符時,在\後面出現的字元可能會實作另外一種意義。
作為續行符時,在行尾使用了\後,可以換行繼續書寫内容。
str = '123'\
'456'
print(str)
---
123456
列印結果看,并未換行,說明續行符起作用了。
- \n 代表一個換行符
str = "歲月是一把殺豬刀, \n但是它拿長得醜的人一點辦法都沒有。"
print(str)
---
歲月是一把殺豬刀,
但是它拿長得醜的人一點辦法都沒有。
- \r代表光标位置(從\r出現的位置開始作為光标的起點)
str = "歲月是一把殺豬刀, \r但是它拿長得醜的人一點辦法都沒有。"
print(str)
---
但是它拿長得醜的人一點辦法都沒有。
- \t代表一個水準制表符(table 縮進)
str = "歲月是一把殺豬刀\t但是它拿長得醜的人一點辦法都沒有。"
print(str)
---
歲月是一把殺豬刀 但是它拿長得醜的人一點辦法都沒有。
- \b 代表一個倒退符
str = "歲月是一把殺豬刀\b但是它拿長得醜的人一點辦法都沒有。"
print(str)
---
歲月是一把殺豬但是它拿長得醜的人一點辦法都沒有。
注意看,并不是毫無改變的列印出來了,整句話中\b前面的刀這個字被倒退了。
- \\ 反轉義\,輸出了\,取消\的轉義效果
str = "歲月是一把殺豬刀\\n但是它拿長得醜的人一點辦法都沒有。"
print(str)
---
歲月是一把殺豬刀\n但是它拿長得醜的人一點辦法都沒有。
第二個\被前面的\轉義了,是以n就不會再被轉義,也就沒有換行。
- r, 如果我們想把轉義字元也作為普通字元輸出,那我們可以在字元串的最前面加上r
str = r"歲月是一把殺豬刀\n但是它拿長得醜的人一點辦法都沒有。"
print(str)
---
歲月是一把殺豬刀\n但是它拿長得醜的人一點辦法都沒有。
字元串内的轉移字元\n被列印了出來。
字元串相關的操作
- 字元串+操作, 将參與運算的字元串相加後組成一個新的字元串。
str="君不見,黃河之水天上來,奔流到海不複回。"
str2 = "君不見,高堂明鏡悲白發,朝如青絲暮成雪。"
res = '将進酒\n'+ str + '\n' + str2
print(res)
---
将進酒
君不見,黃河之水天上來,奔流到海不複回。
君不見,高堂明鏡悲白發,朝如青絲暮成雪。
- 字元串*操作,str*n就是 将目前字元串重複n遍
str = '重要的話說三遍\n' * 3
print(str)
---
重要的話說三遍
重要的話說三遍
重要的話說三遍
- 字元串[]切片操作
字元串的索引操作,字元串中隻能使用[]下标通路,不能修改。
str[start:stop:step]
功能,擷取str的特定下标或者對str進行切片操作
參數:
start: 可選,開始值,預設為0
stop: 可選,結束值,預設為len(str)
step:可選,步進值,預設為1
因為所有參數都是可選項,是以其實我們可以什麼參數都不給,直接使用預設值:
str = '凡詩之所謂風者,多出于裡巷歌謠之作,所謂男女相與詠歌,各言其情者也。'
print(str)
# 等同于
print(str[::])
---
凡詩之所謂風者,多出于裡巷歌謠之作,所謂男女相與詠歌,各言其情者也。
凡詩之所謂風者,多出于裡巷歌謠之作,所謂男女相與詠歌,各言其情者也。
當我們寫一個值,那就是擷取指定下标的元素:
print(str[6])
---
者
但是當我們隻寫一個值,并且後面跟上符号::, 那含義就是從start開始,向後取完:
print(str[6::])
---
者,多出于裡巷歌謠之作,所謂男女相與詠歌,各言其情者也。
從這我們可以看出來,當我們隻寫一個單獨的值而沒有加::的時候,含義就是從start開始,但是并不向後繼續取值,而有了::就是繼續向後取值。其實,隻寫一個:也是一樣的,因為隻要知道向後取值,step預設值就是為1:
print(str[6:])
---
者,多出于裡巷歌謠之作,所謂男女相與詠歌,各言其情者也。
那如果我們在這個基礎上加上一個值,那就是從start開始直到stop之前。和range()一樣,取不到stop。
print(str[2:6])
---
之所謂風
然後再多加一個值,和range()一樣,就是往後數step個數再取值:
print(str[2:15:2])
---
之謂者多于巷謠
其實,這裡比較饒的并不是如何取值,二是::這兩個符号。當我們将上面講的這些内容了解通透後,就可以玩轉字元串的切片了。
那對應的,如果我們想将字元串完全取值,但是是隔一個取一個,那我們就可以使用start和stop的預設值,而隻定義step
print(str[::2])
---
凡之謂者多于巷謠作所男相詠,言情也
那如果我們想讓整個字元串倒過來呢?
print(str[::-1])
---
。也者情其言各,歌詠與相女男謂所,作之謠歌巷裡于出多,者風謂所之詩凡
字元串的格式化方法
常用的字元串的格式化方法就是format()
先讓我們看看最普通的方式:
s = '茶桁'
str = '乘舟将欲行,忽聞岸上踏歌聲。'
我定義了這兩個字元串,現在我想将兩段字元串合在一起變成一句“茶桁乘舟将欲行,忽聞岸上踏歌聲。”(嗯,權吾乃青蓮居士。)
很多小夥伴是不是覺得太簡單了,我們之前學了+号,直接拼接不就好了。自然也是可以的,隻是我們現在要用更普遍和便捷的方式來完成:
s = '茶桁'
str = '{}乘舟将欲行,忽聞岸上踏歌聲。'.format(s)
print(str)
---
茶桁乘舟将欲行,忽聞岸上踏歌聲。
假如說,我們現在隻有詩詞的大半句,其中少了踏歌行這三個字,那我們又該如何?那我們就往format中傳入兩個參數,後面那個參數自定義出這三個字元就可以了:
s = '茶桁'
str = '{}乘舟将欲行,忽聞岸上{}。'.format(s, "踏歌行")
print(str)
---
茶桁乘舟将欲行,忽聞岸上踏歌行。
看到這裡,我們是不是認為字元串使用format就隻能順序傳值?第一個答案填入第一個空,第二個答案填入第二個空... 其實不隻是如此,字元串後使用format,其中的{}還可以接受索引傳參:
s = '茶桁'
str = '{1}乘舟将欲行,忽聞岸上{0}。'.format("踏歌行", s)
print(str)
---
茶桁乘舟将欲行,忽聞岸上踏歌行。
通過索引傳參的适用範圍畢竟還是有限,我們很容易一不小心就會把參數順序搞亂。那還有沒有其他辦法呢?
我們還可以通過關鍵字傳參:
str = '{s2}乘舟将欲行,忽聞岸上{s1}。'.format(s1 = "踏歌行", s2 = "茶桁")
print(str)
---
茶桁乘舟将欲行,忽聞岸上踏歌行。
那假如說我們得到的是一個清單資料,是否需要先轉換資料?其實也沒必要,format支援對容器型資料的傳參數:
str = '豪放派:{0[0]},婉約派:{0[1]},流氓派:{0[3]},蛋黃派:{0[2]}'.format(['李白','辛棄疾','達利園','茶桁'])
print(str)
---
豪放派:李白,婉約派:辛棄疾,流氓派:茶桁,蛋黃派:達利園
那麼如果是字典類型的呢?那就更簡單了,我們之前提到的關鍵字傳參,不就正好對應字典嗎?
dict = {'a':'茶桁', 'b':'蛋黃派'}
str = '{a}乘舟将欲行,忽聞岸上{b}'.format(**dict)
print(str)
---
茶桁乘舟将欲行,忽聞岸上蛋黃派
嗯,不錯。似乎我們建立了一句新的詩句。
其實,format還有其他的用法,就是直接用關鍵字f, 比如:
str = f'{dict["a"]}乘舟将欲行,忽聞岸上{dict["b"]}'
print(str)
---
茶桁乘舟将欲行,忽聞岸上蛋黃派
f是在3.7版本中新增的格式化方法,在使用的過程中,要注意字元串符号“”和‘’的嵌套關系。
在基本使用之外,我們還有一些風騷的特殊用法,比如,我們可以用format直接限定小數的位數:
str = '圓周率是多少:{:.5f}'.format(3.1415926)
print(str)
---
圓周率是多少:3.14159
字元串相關函數
在Python中,字元串應該是最常見的資料類型,對應字元串的函數也有不少。大家可以去看看官方的文檔
英文字元與字元檢測相關函數
我們可以傳回字元串的副本,并且将首字母大寫,其餘小寫:
str = 'I am a data product manager'
str.capitalize()
---
'I am a data product manager'
因為我在使用Jupyter Notebook,是以即便我麼有使用print,依然可以列印出執行結果。隻是僅可以列印最後一個執行的函數。
可以把字元串中的一個單詞的首字母大寫:
str.title()
---
'I Am A Data Product Manager'
可以全部改為大寫:
str.upper()
---
'I AM A DATA PRODUCT MANAGER'
把字元串全部改為小寫
str.lower()
---
'i am a data product manager'
字元串中的大小寫字元轉換,大寫轉小寫,小寫轉大寫:
str.swapcase()
---
'i AM A DATA PRODUCT MANAGER'
檢測字元是否包含在字元串内:
print('o' in 'love')
---
True
檢測字元串是否為全部大寫字母組成
str.isupper()
---
False
檢測字元串是否為全部小寫字母組成
str.islower()
---
False
檢測字元串是否符合标題title的要求
str.istitle()
---
False
檢測字元串是否由數字和字母組成,如果字元串中包含來非數字字母的其它字元,則傳回False
str.isalnum()
---
False
檢測字元串是否全部由字元(包含英文字元和中文)組成
str.isalpha()
---
False
檢測字元串是否由純數字字元組成
'123'.isdigit()
---
True
檢測目前字元串是否為 空格 字元組成 ' ’
' '.isspace()
---
True
檢測字元串是否以指定的字元開始的,也可以指定開始和結束的位置
str.startswith('I')
---
True
str.startswith('a', 5)
---
True
檢測字元串是否以 指定的字元 結束的,也可以指定開始和結束的位置
print(str.endswith('a'))
print(str.endswith('a', 5, 11))
print(str.endswith('a', 1, 6))
---
False
True
True
字元串的查找和操作相關函數(✨ 重點)
前面鋪墊了那麼多之後,接下來這部分,才是這一節的重點。
讓我們先從查找來看:
str.find(sub[, start[, end]])
find會傳回一個子字元串,找到字元中符合條件的第一個字元出現的索引位置,未找到則傳回-1
str = "I am a data product manager."
print(str.find('am'))
---
2
讓我們用切片的方式反過來找一下看看:
res = str.find('am')
str[res:res+2]
---
'am'
我們從之前可以知道res取值為2,現在等于是str[2:4], 正好是am所在的位置。
find中有start和end,是支援切片查找的:
print(str.find('am', 0, 4))
print(str.find('am', 4, 10))
---
2
-1
可以看到,在從4開始找到10的時候找不到am, find有一個功能相同,但是方向不同的方法rfind(), 和find的不同點隻是,rfind是從後往前找的。
str.index(sub[, start[, end]])
類似于find(), 但在找不到子字元串的時候會引發ValueError
str.index('python')
---
ValueError: substring not found
str.count(sub[, start[, end]])
這個函數會在字元串中去查找sub在其中[start, end]範圍内非重疊出現的次數。
print(str.count('a'))
print(str.count('a', 5, 12))
---
6
3
接下來讓我們看看字元串操作相關的函數:
str.split(sep=None, maxsplit=-1)
這個方法可以按照指定的分隔符(sep),把字元串分隔成清單。
str = 'user_admin_id_123'
str.split('_')
---
['user', 'admin', 'id', '123']
整個方法裡的maxsplit是進行多少次拆分,比如1為一次拆分,也就是會傳回2個元素。預設值為-1,意思是不限制拆分次數。
str.split('_', 1)
---
['user', 'admin_id_123']
str.rsplit(sep=None, maxsplit=-1)
和split方法相似,隻是方向不同。這個是從後向前擷取。
str.rsplit('_')
---
['user', 'admin', 'id', '123']
這段代碼可以看到功能上是完全一樣的,如果我們把maxsplit加進去,就能看到方向上的不同:
str.rsplit('_', 1)
---
['user_admin_id', '123']
這樣就能清晰看到,rsplit是從後面開始拆分的。
str.join(iterable)
join的功能和split可以看成是相反的,是使用指定的字元串,把一個容器中的元素連接配接成一整個字元串
str = ['user', 'admin', 'id', '123']
'_'.join(str)
---
'user_admin_id_123'
str.strip([chars])
去除字元串左右兩側的指定字元, chars參數為置頂要溢出字元的字元串,預設移除空白符。
str = ' chaheng '
str.strip(' ')
---
'chaheng'
這個函數有兩個伴生函數,一個是rstrip, 從方法名應該能猜的出來,這是去掉字元串右側的指定字元,另一個是lstrip, 這是去除左側的指定字元。
str.rstrip(' ')
str.lstrip(' ')
---
' chaheng'
'chaheng '
len()函數可以擷取目前字元串的長度
len(str)
---
9
str.replace(old, new[, count])
可以替換對應的字元串,将old都替稱為new。count則是替換次數。比如一個字元串内出現了十次old, 我``count給的5, 則隻替換前5次出現的old`字元串。
str = 'abcabcabcabcabcabc'
str.replace('a', 'e')
str.replace('a', 'e', 2)
---
'ebcebcebcebcebcebc'
'ebcebcabcabcabcabc'
可以注意一下兩次列印的差別。
這次就不留練習題了,字元串的查詢和操作函數屬于重中之重,大家最好是多去練習幾遍,将其中的方法記會杯熟。
好,今天就到這裡。咱們下節課再見。