關于字符串的內容,已經有兩節進行介紹了。不過,它是一個話題中心,還要再繼續。
例如這樣一個字符串`python`,還記得前面對字符串的定義嗎?它就是幾個字符:p,y,t,h,o,n,排列起來。這種排列是非常嚴格的,不僅僅是字符本身,而且還有順序,換言之,如果某個字符換了,就編程一個新字符串了;如果這些字符順序發生變化了,也成為了一個新字符串。
在python中,把像字符串這樣的對象類型(后面還會冒出來類似的其它有這種特點的對象類型,比如列表),統稱為序列。顧名思義,序列就是“有序排列”。
比如水泊梁山的108個好漢(里面分明也有女的,難道女漢子是從這里來的嗎?),就是一個“有序排列”的序列。從老大宋江一直排到第108位金毛犬段景住。在這個序列中,每個人有編號,編號和每個人一一對應。1號是宋江,2號是盧俊義。反過來,通過每個人的姓名,也能找出他對應的編號。武松是多少號?14號。李逵呢?22號。
在python中,給這些編號取了一個文雅的名字,叫做**索引**(別的編程語言也這么稱呼,不是python獨有的。)。
## [](https://github.com/qiwsir/StarterLearningPython/blob/master/108.md#索引和切片)索引和切片
前面用梁山好漢的為例說明了索引。再看python中的例子:
~~~
>>> lang = "study python"
>>> lang[0]
's'
>>> lang[1]
't'
~~~
有一個字符串,通過賦值語句賦給了變量lang。如果要得到這個字符串的第一個單詞`s`,可以用`lang[0]`。當然,如果你不愿意通過賦值語句,讓變量lang來指向那個字符串,也可以這樣做:
~~~
>>> "study python"[0]
's'
~~~
效果是一樣的。因為lang是標簽,就指向了`"study python"`字符串。當讓python執行`lang[0]`的時候,就是要轉到那個字符串對象,如同上面的操作一樣。只不過,如果不用lang這么一個變量,后面如果再寫,就費筆墨了,要每次都把那個字符串寫全了。為了省事,還是復制給一個變量吧。變量就是字符串的代表了。
字符串這個序列的排序方法跟梁山好漢有點不同,第一個不是用數字1表示,而是用數字0表示。不僅僅python,其它很多語言都是從0開始排序的。為什么這樣做呢?這就是規定。當然,這個規定是有一定優勢的。此處不展開,有興趣的網上去google一下,有專門對此進行解釋的文章。
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| s | t | u | d | y | | p | y | t | h | o | n |
上面的表格中,將這個字符串從第一個到最后一個進行了排序,特別注意,兩個單詞中間的那個空格,也占用了一個位置。
通過索引能夠找到該索引所對應的字符,那么反過來,能不能通過字符,找到其在字符串中的索引值呢?怎么找?
~~~
>>> lang.index("p")
6
~~~
就這樣,是不是已經能夠和梁山好漢的例子對上號了?只不過區別在于第一個的索引值是0。
如果某一天,宋大哥站在大石頭上,向著各位弟兄大喊:“兄弟們,都排好隊。”等兄弟們排好之后,宋江說:“現在給各位沒有老婆的兄弟分配女朋友,我這里已經有了名單,我念叨的兄弟站出來。不過我是按照序號來念的。第29號到第34號先出列,到旁邊房子等候分配女朋友。”
在前面的例子中lang[1]能夠得到原來字符串的第二個字符t,就相當于從原來字符串中把這個“切”出來了。不過,我們這么“切”卻不影響原來字符串的完整性,當然可以理解為將那個字符t賦值一份拿出來了。
那么宋江大哥沒有一個一個“切”,而是一下將幾個兄弟叫出來。在python中也能做類似事情。
~~~
>>> lang
'study python' #在前面“切”了若干的字符之后,再看一下該字符串,還是完整的。
>>> lang[2:9]
'udy pyt'
~~~
通過`lang[2:9]`要得到部分(不是一個)字符,從返回的結果中可以看出,我們得到的是序號分別對應著`2,3,4,5,6,7,8`(跟上面的表格對應一下)字符(包括那個空格)。也就是,這種獲得部分字符的方法中,能夠得到開始需要的以及最后一個序號之前的所對應的字符。有點拗口,自己對照上面的表格數一數就知道了。簡單說就是包括開頭,不包括結尾。
上述,不管是得到一個還是多個,通過索引得到字符的過程,稱之為**切片**。
切片是一個很有意思的東西。可以“切”出不少花樣呢?
~~~
>>> lang
'study python'
>>> b = lang[1:] #得到從1號到最末尾的字符,這時最后那個需要不用寫
>>> b
'tudy python'
>>> c = lang[:] #得到所有字符
>>> c
'study python'
>>> d = lang[:10] #得到從第一個到10號之前的字符
>>> d
'study pyth'
~~~
在獲取切片的時候,如果分號的前面或者后面的序號不寫,就表示是到最末(后面的不寫)或第一個(前面的不寫)
`lang[:10]`的效果和`lang[0:10]`是一樣的。
~~~
>>> e = lang[0:10]
>>> e
'study pyth'
~~~
那么,`lang[1:]`和`lang[1:11]`效果一樣嗎?請思考后作答。
~~~
>>> lang[1:11]
'tudy pytho'
>>> lang[1:]
'tudy python'
~~~
果然不一樣,你思考對了嗎?原因就是前述所說的,如果分號后面有數字,所得到的切片,不包含該數字所對應的序號(前包括,后不包括)。那么,是不是可以這樣呢?`lang[1:12]`,不包括12號(事實沒有12號),是不是可以得到1到11號對應的字符呢?
~~~
>>> lang[1:12]
'tudy python'
>>> lang[1:13]
'tudy python'
~~~
果然是。并且不僅僅后面寫12,寫13,也能得到同樣的結果。但是,我這個特別要提醒,這種獲得切片的做法在編程實踐中是不提倡的。特別是如果后面要用到循環的時候,這樣做或許在什么時候遇到麻煩。
如果在切片的時候,冒號左右都不寫數字,就是前面所操作的`c = lang[:]`,其結果是變量c的值與原字符串一樣,也就是“復制”了一份。注意,這里的“復制”我打上了引號,意思是如同復制,是不是真的復制呢?可以用下面的方式檢驗一下
~~~
>>> id(c)
3071934536L
>>> id(lang)
3071934536L
~~~
`id()`的作用就是查看該對象在內存地址(就是在內存中的位置編號)。從上面可以看出,兩個的內存地址一樣,說明c和lang兩個變量指向的是同一個對象。用`c=lang[:]`的方式,并沒有生成一個新的字符串,而是將變量c這個標簽也貼在了原來那個字符串上了。
~~~
>>> lang = "study python"
>>> c = lang
~~~
如果這樣操作,變量c和lang是不是指向同一個對象呢?或者兩者所指向的對象內存地址如何呢?看官可以自行查看。
## [](https://github.com/qiwsir/StarterLearningPython/blob/master/108.md#字符串基本操作)字符串基本操作
字符串是一種序列,所有序列都有如下基本操作:
1. len():求序列長度
2. + :連接2個序列
3. * : 重復序列元素
4. in :判斷元素是否存在于序列中
5. max() :返回最大值
6. min() :返回最小值
7. cmp(str1,str2) :比較2個序列值是否相同
通過下面的例子,將這幾個基本操作在字符串上的使用演示一下:
### [](https://github.com/qiwsir/StarterLearningPython/blob/master/108.md#連接字符串)“+”連接字符串
~~~
>>> str1 + str2
'abcdabcde'
>>> str1 + "-->" + str2
'abcd-->abcde'
~~~
這其實就是拼接,不過在這里,看官應該有一個更大的觀念,我們現在只是學了字符串這一種序列,后面還會遇到列表、元組兩種序列,都能夠如此實現拼接。
### [](https://github.com/qiwsir/StarterLearningPython/blob/master/108.md#in)in
~~~
>>> "a" in str1
True
>>> "de" in str1
False
>>> "de" in str2
True
~~~
`in`用來判斷某個字符串是不是在另外一個字符串內,或者說判斷某個字符串內是否包含某個字符串,如果包含,就返回`True`,否則返回`False`。
### [](https://github.com/qiwsir/StarterLearningPython/blob/master/108.md#最值)最值
~~~
>>> max(str1)
'd'
>>> max(str2)
'e'
>>> min(str1)
'a'
~~~
一個字符串中,每個字符在計算機內都是有編碼的,也就是對應著一個數字,`min()`和`max()`就是根據這個數字里獲得最小值和最大值,然后對應出相應的字符。關于這種編號是多少,看官可以google有關字符編碼,或者ASCII編碼什么的,很容易查到。
### [](https://github.com/qiwsir/StarterLearningPython/blob/master/108.md#比較)比較
~~~
>>> cmp(str1, str2)
-1
~~~
將兩個字符串進行比較,也是首先將字符串中的符號轉化為對一個的數字,然后比較。如果返回的數值小于零,說明第一個小于第二個,等于0,則兩個相等,大于0,第一個大于第二個。為了能夠明白其所以然,進入下面的分析。
~~~
>>> ord('a')
97
>>> ord('b')
98
>>> ord(' ')
32
~~~
`ord()`是一個內建函數,能夠返回某個字符(注意,是一個字符,不是多個字符組成的串)所對一個的ASCII值(是十進制的),字符a在ASCII中的值是97,空格在ASCII中也有值,是32。順便說明,反過來,根據整數值得到相應字符,可以使用`chr()`:
~~~
>>> chr(97)
'a'
>>> chr(98)
'b'
~~~
于是,就得到如下比較結果了:
~~~
>>> cmp("a","b") #a-->97, b-->98, 97小于98,所以a小于b
-1
>>> cmp("abc","aaa")
1
>>> cmp("a","a")
0
~~~
看看下面的比較,是怎么進行的呢?
~~~
>>> cmp("ad","c")
-1
~~~
在字符串的比較中,是兩個字符串的第一個字符先比較,如果相等,就比較下一個,如果不相等,就返回結果。直到最后,如果還相等,就返回0。位數不夠時,按照沒有處理(注意,沒有不是0,0在ASCII中對應的是NUL),位數多的那個天然大了。ad中的a先和后面的c進行比較,顯然a小于c,于是就返回結果-1。如果進行下面的比較,是最容易讓人迷茫的。看官能不能根據剛才闡述的比較遠離理解呢?
~~~
>>> cmp("123","23")
-1
>>> cmp(123,23) #也可以比較整數,這時候就是整數的直接比較了。
1
~~~
### [](https://github.com/qiwsir/StarterLearningPython/blob/master/108.md#)“*”
字符串中的“乘法”,這個乘法,就是重復那個字符串的含義。在某些時候很好用的。比如我要打印一個華麗的分割線:
~~~
>>> str1*3
'abcdabcdabcd'
>>> print "-"*20 #不用輸入很多個`-`
--------------------
~~~
### [](https://github.com/qiwsir/StarterLearningPython/blob/master/108.md#len)len()
要知道一個字符串有多少個字符,一種方法是從頭開始,盯著屏幕數一數。哦,這不是計算機在干活,是鍵客在干活。
> 鍵客,不是劍客。劍客是以劍為武器的俠客;而鍵客是以鍵盤為武器的俠客。當然,還有賤客,那是賤人的最高境界,賤到大俠的程度,比如岳不群之流。
鍵客這樣來數字符串長度:
~~~
>>> a="hello"
>>> len(a)
5
~~~
使用的是一個函數len(object)。得到的結果就是該字符串長度。
~~~
>>> m = len(a) #把結果返回后賦值給一個變量
>>> m
5
>>> type(m) #這個返回值(變量)是一個整數型
<type 'int'>
~~~
- 第零章 預備
- 關于Python的故事
- 從小工到專家
- Python安裝
- 集成開發環境
- 第壹章 基本數據類型
- 數和四則運算
- 除法
- 常用數學函數和運算優先級
- 寫一個簡單的程序
- 字符串(1)
- 字符串(2)
- 字符串(3)
- 字符串(4)
- 字符編碼
- 列表(1)
- 列表(2)
- 列表(3)
- 回顧list和str
- 元組
- 字典(1)
- 字典(2)
- 集合(1)
- 集合(2)
- 第貳章 語句和文件
- 運算符
- 語句(1)
- 語句(2)
- 語句(3)
- 語句(4)
- 語句(5)
- 文件(1)
- 文件(2)
- 迭代
- 練習
- 自省
- 第叁章 函數
- 函數(1)
- 函數(2)
- 函數(3)
- 函數(4)
- 函數練習
- 第肆章 類
- 類(1)
- 類(2)
- 類(3)
- 類(4)
- 類(5)
- 多態和封裝
- 特殊方法(1)
- 特殊方法(2)
- 迭代器
- 生成器
- 上下文管理器
- 第伍章 錯誤和異常
- 錯誤和異常(1)
- 錯誤和異常(2)
- 錯誤和異常(3)
- 第陸章 模塊
- 編寫模塊
- 標準庫(1)
- 標準庫(2)
- 標準庫(3)
- 標準庫(4)
- 標準庫(5)
- 標準庫(6)
- 標準庫(7)
- 標準庫(8)
- 第三方庫
- 第柒章 保存數據
- 將數據存入文件
- mysql數據庫(1)
- MySQL數據庫(2)
- mongodb數據庫(1)
- SQLite數據庫
- 電子表格
- 第捌章 用Tornado做網站
- 為做網站而準備
- 分析Hello
- 用tornado做網站(1)
- 用tornado做網站(2)
- 用tornado做網站(3)
- 用tornado做網站(4)
- 用tornado做網站(5)
- 用tornado做網站(6)
- 用tornado做網站(7)
- 第玖章 科學計算
- 為計算做準備
- Pandas使用(1)
- Pandas使用(2)
- 處理股票數據
- 附:網絡文摘
- 如何成為Python高手
- ASCII、Unicode、GBK和UTF-8字符編碼的區別聯系