鍍金池/ 教程/ Python/ 字符串(3)
標(biāo)準(zhǔn)庫(kù) (4)
如何成為 Python 高手
標(biāo)準(zhǔn)庫(kù) (6)
標(biāo)準(zhǔn)庫(kù) (3)
類(2)
Pandas 使用 (2)
xml
用 tornado 做網(wǎng)站 (5)
文件(1)
練習(xí)
列表(3)
從小工到專家
除法
錯(cuò)誤和異常 (2)
函數(shù)(1)
用 tornado 做網(wǎng)站 (7)
為做網(wǎng)站而準(zhǔn)備
函數(shù)練習(xí)
標(biāo)準(zhǔn)庫(kù) (8)
Pandas 使用 (1)
回顧 list 和 str
字典(1)
用 tornado 做網(wǎng)站 (3)
字符串(1)
函數(shù)(2)
寫(xiě)一個(gè)簡(jiǎn)單的程序
將數(shù)據(jù)存入文件
語(yǔ)句(5)
SQLite 數(shù)據(jù)庫(kù)
集成開(kāi)發(fā)環(huán)境(IDE)
集合(1)
類(1)
用 tornado 做網(wǎng)站 (6)
用 tornado 做網(wǎng)站 (2)
自省
語(yǔ)句(4)
錯(cuò)誤和異常 (1)
用 tornado 做網(wǎng)站 (4)
集合(2)
列表(1)
標(biāo)準(zhǔn)庫(kù) (1)
生成器
mysql 數(shù)據(jù)庫(kù) (1)
第三方庫(kù)
實(shí)戰(zhàn)
運(yùn)算符
類(3)
字典(2)
語(yǔ)句(1)
數(shù)和四則運(yùn)算
語(yǔ)句(2)
文件(2)
MySQL 數(shù)據(jù)庫(kù) (2)
電子表格
迭代器
mongodb 數(shù)據(jù)庫(kù) (1)
特殊方法 (2)
特殊方法 (1)
字符編碼
編寫(xiě)模塊
用 tornado 做網(wǎng)站 (1)
標(biāo)準(zhǔn)庫(kù) (5)
函數(shù)(4)
類(5)
字符串(2)
關(guān)于 Python 的故事
函數(shù)(3)
字符串(4)
處理股票數(shù)據(jù)
常用數(shù)學(xué)函數(shù)和運(yùn)算優(yōu)先級(jí)
字符串(3)
為計(jì)算做準(zhǔn)備
多態(tài)和封裝
類(4)
迭代
語(yǔ)句(3)
錯(cuò)誤和異常 (3)
分析 Hello
Python 安裝
標(biāo)準(zhǔn)庫(kù) (2)
列表(2)
元組

字符串(3)

關(guān)于字符串的內(nèi)容,已經(jīng)有兩節(jié)進(jìn)行介紹了。不過(guò),它是一個(gè)話題中心,還要再繼續(xù)。

例如這樣一個(gè)字符串 Python,還記得前面對(duì)字符串的定義嗎?它就是幾個(gè)字符:P,y,t,h,o,n,排列起來(lái)。這種排列是非常嚴(yán)格的,不僅僅是字符本身,而且還有順序,換言之,如果某個(gè)字符換了,就編程一個(gè)新字符串了;如果這些字符順序發(fā)生變化了,也成為了一個(gè)新字符串。

在 Python 中,把像字符串這樣的對(duì)象類型(后面還會(huì)冒出來(lái)類似的其它有這種特點(diǎn)的對(duì)象類型,比如列表),統(tǒng)稱為序列。顧名思義,序列就是“有序排列”。

比如水泊梁山的 108 個(gè)好漢(里面分明也有女的,難道女漢子是從這里來(lái)的嗎?),就是一個(gè)“有序排列”的序列。從老大宋江一直排到第 108 位金毛犬段景住。在這個(gè)序列中,每個(gè)人有編號(hào),編號(hào)和每個(gè)人一一對(duì)應(yīng)。1 號(hào)是宋江,2 號(hào)是盧俊義。反過(guò)來(lái),通過(guò)每個(gè)人的姓名,也能找出他對(duì)應(yīng)的編號(hào)。武松是多少號(hào)?14 號(hào)。李逵呢?22 號(hào)。

在 Python 中,給這些編號(hào)取了一個(gè)文雅的名字,叫做索引(別的編程語(yǔ)言也這么稱呼,不是 Python 獨(dú)有的。)。

索引和切片

前面用梁山好漢的為例說(shuō)明了索引。再看 Python 中的例子:

>>> lang = "study Python"
>>> lang[0]
's'
>>> lang[1]
't'

有一個(gè)字符串,通過(guò)賦值語(yǔ)句賦給了變量 lang。如果要得到這個(gè)字符串的第一個(gè)單詞 s,可以用 lang[0]。當(dāng)然,如果你不愿意通過(guò)賦值語(yǔ)句,讓變量 lang 來(lái)指向那個(gè)字符串,也可以這樣做:

>>> "study Python"[0]
's'

效果是一樣的。因?yàn)?lang 是標(biāo)簽,就指向了 "study Python" 字符串。當(dāng)讓 Python 執(zhí)行 lang[0] 的時(shí)候,就是要轉(zhuǎn)到那個(gè)字符串對(duì)象,如同上面的操作一樣。只不過(guò),如果不用 lang 這么一個(gè)變量,后面如果再寫(xiě),就費(fèi)筆墨了,要每次都把那個(gè)字符串寫(xiě)全了。為了省事,還是復(fù)制給一個(gè)變量吧。變量就是字符串的代表了。

字符串這個(gè)序列的排序方法跟梁山好漢有點(diǎn)不同,第一個(gè)不是用數(shù)字1表示,而是用數(shù)字 0 表示。不僅僅 Python,其它很多語(yǔ)言都是從 0 開(kāi)始排序的。為什么這樣做呢?這就是規(guī)定。當(dāng)然,這個(gè)規(guī)定是有一定優(yōu)勢(shì)的。此處不展開(kāi),有興趣的網(wǎng)上去 google 一下,有專門對(duì)此進(jìn)行解釋的文章。

0 1 2 3 4 5 6 7 8 9 10 11
s t u d y l p y t h o n

上面的表格中,將這個(gè)字符串從第一個(gè)到最后一個(gè)進(jìn)行了排序,特別注意,兩個(gè)單詞中間的那個(gè)空格,也占用了一個(gè)位置。

通過(guò)索引能夠找到該索引所對(duì)應(yīng)的字符,那么反過(guò)來(lái),能不能通過(guò)字符,找到其在字符串中的索引值呢?怎么找?

>>> lang.index("p")
6

就這樣,是不是已經(jīng)能夠和梁山好漢的例子對(duì)上號(hào)了?只不過(guò)區(qū)別在于第一個(gè)的索引值是 0。

如果某一天,宋大哥站在大石頭上,向著各位弟兄大喊:“兄弟們,都排好隊(duì)?!钡刃值軅兣藕弥?,宋江說(shuō):“現(xiàn)在給各位沒(méi)有老婆的兄弟分配女朋友,我這里已經(jīng)有了名單,我念叨的兄弟站出來(lái)。不過(guò)我是按照序號(hào)來(lái)念的。第 29 號(hào)到第 34 號(hào)先出列,到旁邊房子等候分配女朋友?!?/p>

在前面的例子中 lang[1] 能夠得到原來(lái)字符串的第二個(gè)字符 t,就相當(dāng)于從原來(lái)字符串中把這個(gè)“切”出來(lái)了。不過(guò),我們這么“切”卻不影響原來(lái)字符串的完整性,當(dāng)然可以理解為將那個(gè)字符 t 賦值一份拿出來(lái)了。

那么宋江大哥沒(méi)有一個(gè)一個(gè)“切”,而是一下將幾個(gè)兄弟叫出來(lái)。在 Python 中也能做類似事情。

>>> lang
'study Python'    #在前面“切”了若干的字符之后,再看一下該字符串,還是完整的。
>>> lang[2:9]
'udy pyt'

通過(guò) lang[2:9]要得到部分(不是一個(gè))字符,從返回的結(jié)果中可以看出,我們得到的是序號(hào)分別對(duì)應(yīng)著 2,3,4,5,6,7,8(跟上面的表格對(duì)應(yīng)一下)字符(包括那個(gè)空格)。也就是,這種獲得部分字符的方法中,能夠得到開(kāi)始需要的以及最后一個(gè)序號(hào)之前的所對(duì)應(yīng)的字符。有點(diǎn)拗口,自己對(duì)照上面的表格數(shù)一數(shù)就知道了。簡(jiǎn)單說(shuō)就是包括開(kāi)頭,不包括結(jié)尾。

上述,不管是得到一個(gè)還是多個(gè),通過(guò)索引得到字符的過(guò)程,稱之為切片

切片是一個(gè)很有意思的東西。可以“切”出不少花樣呢?

>>> lang
'study Python'
>>> b = lang[1:]    # 得到從 1 號(hào)到最末尾的字符,這時(shí)最后那個(gè)需要不用寫(xiě)
>>> b
'tudy Python'
>>> c = lang[:]    # 得到所有字符
>>> c
'study Python'
>>> d = lang[:10]    # 得到從第一個(gè)到 10 號(hào)之前的字符
>>> d
'study pyth'

在獲取切片的時(shí)候,如果分號(hào)的前面或者后面的序號(hào)不寫(xiě),就表示是到最末(后面的不寫(xiě))或第一個(gè)(前面的不寫(xiě))

lang[:10]的效果和 lang[0:10]是一樣的。

>>> e = lang[0:10]
>>> e
'study pyth'

那么,lang[1:]lang[1:11]效果一樣嗎?請(qǐng)思考后作答。

>>> lang[1:11]
'tudy pytho'
>>> lang[1:]
'tudy python'

果然不一樣,你思考對(duì)了嗎?原因就是前述所說(shuō)的,如果分號(hào)后面有數(shù)字,所得到的切片,不包含該數(shù)字所對(duì)應(yīng)的序號(hào)(前包括,后不包括)。那么,是不是可以這樣呢?lang[1:12],不包括 12 號(hào)(事實(shí)沒(méi)有 12 號(hào)),是不是可以得到 1 到 11 號(hào)對(duì)應(yīng)的字符呢?

>>> lang[1:12]
'tudy python'
>>> lang[1:13]
'tudy python'

果然是。并且不僅僅后面寫(xiě) 12,寫(xiě) 13,也能得到同樣的結(jié)果。但是,我這個(gè)特別要提醒,這種獲得切片的做法在編程實(shí)踐中是不提倡的。特別是如果后面要用到循環(huán)的時(shí)候,這樣做或許在什么時(shí)候遇到麻煩。

如果在切片的時(shí)候,冒號(hào)左右都不寫(xiě)數(shù)字,就是前面所操作的 c = lang[:],其結(jié)果是變量 c 的值與原字符串一樣,也就是“復(fù)制”了一份。注意,這里的“復(fù)制”我打上了引號(hào),意思是如同復(fù)制,是不是真的復(fù)制呢?可以用下面的方式檢驗(yàn)一下

>>> id(c)
3071934536L
>>> id(lang)
3071934536L

id()的作用就是查看該對(duì)象在內(nèi)存地址(就是在內(nèi)存中的位置編號(hào))。從上面可以看出,兩個(gè)的內(nèi)存地址一樣,說(shuō)明 c 和 lang 兩個(gè)變量指向的是同一個(gè)對(duì)象。用 c=lang[:]的方式,并沒(méi)有生成一個(gè)新的字符串,而是將變量 c 這個(gè)標(biāo)簽也貼在了原來(lái)那個(gè)字符串上了。

>>> lang = "study python"
>>> c = lang

如果這樣操作,變量 c 和 lang 是不是指向同一個(gè)對(duì)象呢?或者兩者所指向的對(duì)象內(nèi)存地址如何呢?看官可以自行查看。

字符串基本操作

字符串是一種序列,所有序列都有如下基本操作:

  1. len():求序列長(zhǎng)度
    • :連接 2 個(gè)序列
    • : 重復(fù)序列元素
  2. in :判斷元素是否存在于序列中
  3. max() :返回最大值
  4. min() :返回最小值
  5. cmp(str1,str2) :比較 2 個(gè)序列值是否相同

通過(guò)下面的例子,將這幾個(gè)基本操作在字符串上的使用演示一下:

“+”連接字符串

>>> str1 + str2
'abcdabcde'
>>> str1 + "-->" + str2
'abcd-->abcde'

這其實(shí)就是拼接,不過(guò)在這里,看官應(yīng)該有一個(gè)更大的觀念,我們現(xiàn)在只是學(xué)了字符串這一種序列,后面還會(huì)遇到列表、元組兩種序列,都能夠如此實(shí)現(xiàn)拼接。

in

>>> "a" in str1
True
>>> "de" in str1
False
>>> "de" in str2
True

in 用來(lái)判斷某個(gè)字符串是不是在另外一個(gè)字符串內(nèi),或者說(shuō)判斷某個(gè)字符串內(nèi)是否包含某個(gè)字符串,如果包含,就返回 True,否則返回 False。

最值

>>> max(str1)
'd'
>>> max(str2)
'e'
>>> min(str1)
'a'

一個(gè)字符串中,每個(gè)字符在計(jì)算機(jī)內(nèi)都是有編碼的,也就是對(duì)應(yīng)著一個(gè)數(shù)字,min()max()就是根據(jù)這個(gè)數(shù)字里獲得最小值和最大值,然后對(duì)應(yīng)出相應(yīng)的字符。關(guān)于這種編號(hào)是多少,看官可以 google 有關(guān)字符編碼,或者 ASCII 編碼什么的,很容易查到。

比較

>>> cmp(str1, str2)
-1

將兩個(gè)字符串進(jìn)行比較,也是首先將字符串中的符號(hào)轉(zhuǎn)化為對(duì)一個(gè)的數(shù)字,然后比較。如果返回的數(shù)值小于零,說(shuō)明第一個(gè)小于第二個(gè),等于 0,則兩個(gè)相等,大于 0,第一個(gè)大于第二個(gè)。為了能夠明白其所以然,進(jìn)入下面的分析。

>>> ord('a')
97
>>> ord('b')
98
>>> ord(' ')
32

ord()是一個(gè)內(nèi)建函數(shù),能夠返回某個(gè)字符(注意,是一個(gè)字符,不是多個(gè)字符組成的串)所對(duì)一個(gè)的 ASCII 值(是十進(jìn)制的),字符 a 在 ASCII 中的值是 97,空格在 ASCII 中也有值,是 32。順便說(shuō)明,反過(guò)來(lái),根據(jù)整數(shù)值得到相應(yīng)字符,可以使用 chr()

>>> chr(97)
'a'
>>> chr(98)
'b'

于是,就得到如下比較結(jié)果了:

>>> cmp("a","b")    #a-->97, b-->98, 97 小于 98,所以 a 小于 b
-1
>>> cmp("abc","aaa") 
1
>>> cmp("a","a")
0

看看下面的比較,是怎么進(jìn)行的呢?

>>> cmp("ad","c")
-1

在字符串的比較中,是兩個(gè)字符串的第一個(gè)字符先比較,如果相等,就比較下一個(gè),如果不相等,就返回結(jié)果。直到最后,如果還相等,就返回 0。位數(shù)不夠時(shí),按照沒(méi)有處理(注意,沒(méi)有不是 0,0 在 ASCII 中對(duì)應(yīng)的是 NUL),位數(shù)多的那個(gè)天然大了。ad 中的 a 先和后面的 c 進(jìn)行比較,顯然 a 小于 c,于是就返回結(jié)果 -1。如果進(jìn)行下面的比較,是最容易讓人迷茫的??垂倌懿荒芨鶕?jù)剛才闡述的比較遠(yuǎn)離理解呢?

>>> cmp("123","23")
-1
>>> cmp(123,23)    # 也可以比較整數(shù),這時(shí)候就是整數(shù)的直接比較了。
1

“*”

字符串中的“乘法”,這個(gè)乘法,就是重復(fù)那個(gè)字符串的含義。在某些時(shí)候很好用的。比如我要打印一個(gè)華麗的分割線:

>>> str1*3
'abcdabcdabcd'
>>> print "-"*20    # 不用輸入很多個(gè)`-`
--------------------

len()

要知道一個(gè)字符串有多少個(gè)字符,一種方法是從頭開(kāi)始,盯著屏幕數(shù)一數(shù)。哦,這不是計(jì)算機(jī)在干活,是鍵客在干活。

鍵客,不是劍客。劍客是以劍為武器的俠客;而鍵客是以鍵盤為武器的俠客。當(dāng)然,還有賤客,那是賤人的最高境界,賤到大俠的程度,比如岳不群之流。

鍵客這樣來(lái)數(shù)字符串長(zhǎng)度:

>>> a="hello"
>>> len(a)
5

使用的是一個(gè)函數(shù) len(object)。得到的結(jié)果就是該字符串長(zhǎng)度。

>>> m = len(a)  # 把結(jié)果返回后賦值給一個(gè)變量
>>> m
5
>>> type(m)     # 這個(gè)返回值(變量)是一個(gè)整數(shù)型
<type 'int'>

總目錄   |   上節(jié):字符串(2)   |   下節(jié):字符串(4)

如果你認(rèn)為有必要打賞我,請(qǐng)通過(guò)支付寶:qiwsir@126.com,不勝感激。