# Chapter 8 Strings 字符串
Strings are not like integers, floats, and booleans. A string is a sequence, which means it is an ordered collection of other values. In this chapter you’ll see how to access the characters that make up a string, and you’ll learn about some of the methods strings provide.
> 字符串和整形、浮點數以及布爾值很不一樣。一個字符串是一個序列,意味著是對其他值的有序排列。在本章你將學到如何讀取字符串中的字符,你還會學到一些字符串相關的方法。
## 8.1 A string is a sequence 字符串是序列
A string is a sequence of characters. You can access the characters one at a time with the bracket operator:
> 字符串就是一串有序的字符。你可以通過方括號操作符,每次去訪問字符串中的一個字符:
```Python
>>> fruit = 'banana'
>>> fruit = 'banana'
>>> letter = fruit[1]
>>> letter = fruit[1]
```
The second statement selects character number 1 from fruit and assigns it to letter.
> 第二個語句選擇了 fruit 這個字符串的序號為1的字符,并把這個字符賦值給了 letter 這個變量。
(譯者注:思考一下這里的 letter 是一個什么類型的變量。)
The expression in brackets is called an index. The index indicates which character in the sequence you want (hence the name).
But you might not get what you expect:
> 方括號內的內容叫做索引。索引指示了你所指定的字符串中字符的位置(就跟名字差不多)。
> 但你可能發現得到的結果和你預期的有點不一樣:
```Python
>>> letter
>>> letter
'a'
```
For most people, the first letter of 'banana' is b, not a. But for computer scientists, the index is an offset from the beginning of the string, and the offset of the first letter is zero.
> 大多數人都認為banana 的第『1』個字符應該是 b,而不是 a。但對于計算機科學家來說,索引是字符串從頭的偏移量,所以真正的首字母偏移量應該是0.
```Python
>>> letter = fruit[0]
>>> letter = fruit[0]
>>> letter
>>> letter
'b'
```
So b is the 0th letter (“zero-eth”) of 'banana', a is the 1th letter (“one-eth”), and n is the 2th letter (“two-eth”).
> 所以 b 就是字符串 banana 的第『0』個字符,而 a 是第『1』個,n 就是第『2』個了。
As an index you can use an expression that contains variables and operators:
> 你可以在方括號內的索引中使用變量和表達式:
```Python
>>> i = 1
>>> i = 1
>>> fruit[i]
>>> fruit[i]
'a'
>>> fruit[i+1]
>>> fruit[i+1]
'n'
```
But the value of the index has to be an integer. Otherwise you get:
> 但要注意的事,索引的值必須是整形的。否則你就會遇到類型錯誤了:
```Python
>>> letter = fruit[1.5]
>>> letter = fruit[1.5]
TypeError: string indices must be integers
```
## 8.2 len 長度
len is a built-in function that returns the number of characters in a string:
> len 是一個內置函數,會返回一個字符串中字符的長度:
```Python
>>> fruit = 'banana'
>>> fruit = 'banana'
>>> len(fruit) 6
>>> len(fruit) 6
```
To get the last letter of a string, you might be tempted to try something like this:
> 要得到一個字符串的最后一個字符,你可能會想到去利用 len 函數:
```Python
>>> length = len(fruit)
>>> length = len(fruit)
>>> last = fruit[length]
>>> last = fruit[length]
IndexError: string index out of range
```
The reason for the IndexError is that there is no letter in ’banana’ with the index 6. Since we started counting at zero, the six letters are numbered 0 to 5. To get the last character, you have to subtract 1 from length:
> 出現索引錯誤的原因就是banana 這個字符串在第『6』個位置是沒有字母的。因為我們從0開始數,所以這一共6個字母的順序是0到5號。因此要得到最后一次字符,你需要在字符串長度的基礎上減去1才行:
```Python
>>> last = fruit[length-1]
>>> last = fruit[length-1]
>>> last
>>> last
'a'
```
Or you can use negative indices, which count backward from the end of the string. The expression fruit[-1] yields the last letter, fruit[-2] yields the second to last, and so on.
> 或者你也可以用負數索引,意思就是從字符串的末尾向前數幾位。fruit[-1]這個表達式給你最后一個字符,fruit[-2]給出倒數第二個,依此類推。
## 8.3 Traversal with a for loop 用 for 循環進行遍歷
A lot of computations involve processing a string one character at a time. Often they start at the beginning, select each character in turn, do something to it, and continue until the end. This pattern of processing is called a traversal. One way to write a traversal is with a while loop:
> 很多計算過程都需要每次從一個字符串中拿一個字符。一般都是從頭開始,依次得到每個字符,然后做點處理,然后一直到末尾。這種處理模式叫遍歷。寫一個遍歷可以使用 while 循環:
```Python
index = 0
while index < len(fruit):
letter = fruit[index]
print(letter)
index = index + 1
```
This loop traverses the string and displays each letter on a line by itself. The loop condition is index < len(fruit), so when index is equal to the length of the string, the condition is false, and the body of the loop doesn’t run. The last character accessed is the one with the index len(fruit)-1, which is the last character in the string.
> 這個循環遍歷了整個字符串,然后它再把買一個字符顯示在一行上面。循環條件是 index 這個變量小于字符串 fruit 的長度,所以當 index 與字符串長度相等的時候,條件就不成立了,循環體就不運行了。最后一個字符被獲取的時候,index 正好是len(fruit)-1,這就已經是該字符串的最后一個字符了。
As an exercise, write a function that takes a string as an argument and displays the letters backward, one per line.
> 下面就練習一下了,寫一個函數,接收一個字符串做參數,然后倒序顯示每一個字符,每行顯示一個。
Another way to write a traversal is with a for loop:
> 另外一種遍歷的方法就是 for 循環了:
```Python
for letter in fruit:
print(letter)
```
Each time through the loop, the next character in the string is assigned to the variable letter. The loop continues until no characters are left.
> 每次循環之后,字符串中的下一個字符都會賦值給變量 letter。循環在進行到沒有字符剩余的時候就停止了。
The following example shows how to use concatenation (string addition) and a for loop to generate an abecedarian series (that is, in alphabetical order).
> 下面的例子展示了如何使用級聯(字符串加法)以及一個 for 循環來生成一個簡單的序列(用字母表順序)。
In Robert McCloskey’s book Make Way for Ducklings, the names of the ducklings are Jack, Kack, Lack, Mack, Nack, Ouack, Pack, and Quack. This loop outputs these names in order:
> 在 Robert McCloskey 的一本名叫《Make Way for Ducklings》的書中,小鴨子的名字依次為:Jack, Kack, Lack, Mack, Nack, Ouack, Pack, 和Quack。下面這個循環會依次輸出他們的名字:
```Python
prefixes = 'JKLMNOPQ'
suffix = 'ack'
for letter in prefixes:
print(letter + suffix)
```
The output is:
> 輸出結果如下:
```Python
Jack Kack Lack Mack Nack Oack Pack Qack
```
Of course, that’s not quite right because “Ouack” and “Quack” are misspelled. As an exercise, modify the program to fix this error.
> 當然了,有點不準確的地方,因為有“Ouack”和 “Quack”兩處拼寫錯了。做個練習,修改一下程序,改正這個錯誤。
## 8.4 String slices 字符串切片
A segment of a string is called a slice. Selecting a slice is similar to selecting a character:
> 字符串的一段叫做切片。從字符串中選擇一部分做切片,與選擇一個字符有些相似:
```Python
>>> s = 'Monty Python'
>>> s = 'Monty Python'
>>> s[0:5]
>>> s[0:5]
'Monty'
>>> s[6:12]
>>> s[6:12]
'Python'
```
The operator [n:m] returns the part of the string from the “n-eth” character to the “m-eth” character, including the first but excluding the last. This behavior is counter intuitive, but it might help to imagine the indices pointing between the characters, as in Figure 8.1.
> [n:m]這種操作符,會返回字符串中從第『n』個到第『m』個的字符,包含開頭的第『n』個,但不包含末尾的第『m』個。這個設計可能有點違背直覺,但可能有助于想象這個切片在字符串中的方向,如圖8.1。
* * *

Figure 8.1: Slice indices.
* * *
If you omit the first index (before the colon), the slice starts at the beginning of the string. If you omit the second index, the slice goes to the end of the string:
> 如果你忽略了第一個索引(就是冒號前面的那個),切片會默認從字符串頭部開始。如果你忽略了第二個索引,切片會一直包含到最后一位:
```Python
>>> fruit = 'banana'
>>> fruit = 'banana'
>>> fruit[:3]
>>> fruit[:3]
'ban'
>>> fruit[3:]
>>> fruit[3:]
'ana'
```
If the first index is greater than or equal to the second the result is an empty string, represented by two quotation marks:
> 如果兩個索引相等,得到的就是空字符串了,用兩個單引號來表示:
```Python
>>> fruit = 'banana'
>>> fruit = 'banana'
>>> fruit[3:3]
>>> fruit[3:3]
''
```
An empty string contains no characters and has length 0, but other than that, it is the same as any other string.
Continuing this example, what do you think fruit[:] means? Try it and see.
> 空字符串不包含字符,長度為0,除此之外,都與其他字符串是一樣的。
> 那么來練習一下,你覺得 fruit[:]這個是什么意思?在程序中試試吧。
## 8.5 Strings are immutable 字符串不可修改
It is tempting to use the [] operator on the left side of an assignment, with the intention of changing a character in a string. For example:
> 大家總是有可能想試試把方括號在賦值表達式的等號左側,試圖去更改字符串中的某一個字符。比如:
```Python
>>> greeting = 'Hello, world!'
>>> greeting = 'Hello, world!'
>>> greeting[0] = 'J'
>>> greeting[0] = 'J'
TypeError: 'str' object does not support item assignment
```
The “object” in this case is the string and the “item” is the character you tried to assign. For now, an object is the same thing as a value, but we will refine that definition later (Section 10.10).
> 『object』是對象的意思,這里指的是字符串類 string,然后『item』是指你試圖賦值的字符串中的字符。目前來說,一個對象就跟一個值差不多,但后續在第十章第十節我們再對這個定義進行詳細討論。
The reason for the error is that strings are immutable, which means you can’t change an existing string. The best you can do is create a new string that is a variation on the original:
> 產生上述錯誤的原因是字符串是不能被修改的,這意味著你不能對一個已經存在的字符串進行任何改動。你頂多也就能建立一個新字符串,新字符串可以基于舊字符串進行一些改動。
```Python
>>> greeting = 'Hello, world!'
>>> greeting = 'Hello, world!'
>>> new_greeting = 'J' + greeting[1:]
>>> new_greeting = 'J' + greeting[1:]
>>> new_greeting
>>> new_greeting
'Jello, world!'
```
This example concatenates a new first letter onto a slice of greeting. It has no effect on the original string.
> 上面的例子中,對 greeting 這個字符串進行了切片,然后添加了一個新的首字母過去。這并不會對原始字符串有任何影響。(譯者注:也就是 greeting 這個字符串的值依然是原來的值,是不可改變的。)
## 8.6 Searching 搜索
What does the following function do?
> 下面這個函數是干啥的?
```Python
def find(word, letter):
index = 0
while index < len(word):
if word[index] == letter:
return index
index = index + 1
return -1
```
In a sense, find is the inverse of the [] operator. Instead of taking an index and extracting the corresponding character, it takes a character and finds the index where that character appears. If the character is not found, the function returns -1.
> 簡單來說,find 函數,也就是查找,是方括號操作符[]的逆運算。方括號是之道索引然后提取對應的字符,而查找函數是選定一個字符去查找這個字符出現的索引位置。如果字符沒有被報道,函數就返回-1。
This is the first example we have seen of a return statement inside a loop. If word[index] == letter, the function breaks out of the loop and returns immediately.
If the character doesn’t appear in the string, the program exits the loop normally and returns -1.
> 這是我們見過的第一個返回語句位于循環體內的例子。如果word[index]等于letter,函數就跳出循環立刻返回。如果字符在字符串里面沒出現,程序正常退出循環并且返回-1。
This pattern of computation—traversing a sequence and returning when we find what we are looking for—is called a search.
As an exercise, modify find so that it has a third parameter, the index in word where it should start looking.
> 這種計算-遍歷一個序列然后返回我們要找的東西的模式就叫做搜索了。
> 做個練習,修改一下 find 函數,加入第三個參數,這個參數為查找開始的字符串位置。
## 8.7 Looping and counting 循環和計數
The following program counts the number of times the letter a appears in a string:
> 下面這個程序計算了字母 a 在一個字符串中出現的次數:
```Python
word = 'banana'
count = 0
for letter in word:
if letter == 'a':
count = count + 1
print(count)
```
This program demonstrates another pattern of computation called a counter. The variable count is initialized to 0 and then incremented each time an a is found. When the loop exits, count contains the result—the total number of a’s.
> 這一程序展示了另外一種計算模式,叫做計數。變量 count 被初始化為0,然后每次在字符串中找到一個 a,就讓 count 加1.當循環退出的時候,count 就包含了 a 出現的總次數。
As an exercise, encapsulate this code in a function named count, and generalize it so that it accepts the string and the letter as arguments.
Then rewrite the function so that instead of traversing the string, it uses the three-parameter version of find from the previous section.
> 做個練習,把上面的代碼封裝進一個名叫 count 的函數中,泛化一下,一遍讓他接收任何字符串和字幕作為參數。
> 然后再重寫一下這個函數,這次不再讓它遍歷整個字符串,而使用上一節中練習的三參數版本的 find 函數。
## 8.8 String methods 字符串方法
Strings provide methods that perform a variety of useful operations. A method is similar to a function—it takes arguments and returns a value—but the syntax is different. For example, the method upper takes a string and returns a new string with all uppercase letters.
Instead of the function syntax upper(word), it uses the method syntax word.upper().
> 字符串提供了一些方法,這些方法能夠進行很多有用的操作。方法和函數有些類似,也接收參數然后返回一個值,但語法稍微不同。比如,upper 這個方法就讀取一個字符串,返回一個全部為大寫字母的新字符串。
> 與函數的 upper(word)語法不同,方法的語法是 word.upper()。
```Python
>>> word = 'banana'
>>> word = 'banana'
>>> new_word = word.upper()
>>> new_word = word.upper()
>>> new_word 'BANANA'
>>> new_word 'BANANA'
```
This form of dot notation specifies the name of the method, upper, and the name of the string to apply the method to, word. The empty parentheses indicate that this method takes no arguments.
> 這種用點號分隔的方法表明了使用的方法名字為 upper,使用這個方法的字符串的名字為 word。后面括號里面是空白的,表示這個方法不接收參數。
A method call is called an invocation; in this case, we would say that we are invoking upper on word.
> 方法的調用被叫做——調用(譯者注:這真是扯淡,中文都混淆成調用,英文里面 invocation 和 invoke 都有祈禱的意思,和 call 有顯著的意義差別,但中文都混淆成調用,這種例子不勝枚舉,所以大家盡量多讀原版作品。);在這里,我們就說調用了 word 的 upper 方法。
As it turns out, there is a string method named find that is remarkably similar to the function we wrote:
> 結果我們發現string 有一個方法叫做 find,跟我們寫過的函數 find 有驚人的相似:
```Python
>>> word = 'banana'
>>> word = 'banana'
>>> index = word.find('a')
>>> index = word.find('a')
>>> index
>>> index
1
```
In this example, we invoke find on word and pass the letter we are looking for as a parameter.
> 在這里我們調用了 word 的 find 方法,然后給定了我們要找的字母 a 作為一個參數。
Actually, the find method is more general than our function; it can find substrings, not just characters:
> 實際上,這個 find 方法比我們的 find 函數功能更通用;它不僅能查找字符,還能查找字符串:
```Python
>>> word.find('na')
>>> word.find('na')
2
```
By default, find starts at the beginning of the string, but it can take a second argument, the index where it should start:
> 默認情況下 find 方法從字符串的開頭來查找,不過可以給它一個第二個參數,讓它從指定位置查找:
```Python
>>> word.find('na', 3)
>>> word.find('na', 3)
4
```
This is an example of an optional argument; find can also take a third argument, the index where it should stop:
> 這是一個可選參數的例子;find 方法還能接收第三個參數,可以指定查找終止的位置:
```Python
>>> name = 'bob'
>>> name = 'bob'
>>> name.find('b', 1, 2)
>>> name.find('b', 1, 2)
-1
```
This search fails because b does not appear in the index range from 1 to 2, not including 2. Searching up to, but not including, the second index makes find consistent with the slice operator.
> 這個搜索失敗了,因為 b 并沒有在索引1到2且不包括2的字符中間出現。搜索到指定的第三個變量作為索引的位置,但不包括該位置,這就讓 find 方法與切片操作符相一致。
## 8.9 The in operator 運算符 in
The word in is a boolean operator that takes two strings and returns True if the first appears as a substring in the second:
> in 這個詞在字符串操作中是一個布爾操作符,它讀取兩個字符串,如果前者的字符串為后者所包含,就返回真,否則為假:
```Python
>>> 'a' in 'banana'
>>> 'a' in 'banana'
True
>>> 'seed' in 'banana'
>>> 'seed' in 'banana'
False
```
For example, the following function prints all the letters from word1 that also appear in word2:
> 舉個例子,下面的函數顯示所有同時在 word1和 word2當中出現的字母:
```Python
def in_both(word1, word2):
for letter in word1:
if letter in word2:
print(letter)
```
With well-chosen variable names, Python sometimes reads like English. You could read this loop, “for (each) letter in (the first) word, if (the) letter (appears) in (the second) word, print (the) letter.”
Here’s what you get if you compare apples and oranges:
> 選好變量名的話,Python 有時候讀起來就跟英語差不多。你讀一下這個循環,就能發現,『對第一個 word 當中的每一個字母letter,如果這個字母也在第二個 word 當中出現,就輸出這個字母 letter。』
```Python
>>> in_both('apples', 'oranges')
>>> in_both('apples', 'oranges')
a e s
```
## 8.10 String comparison 字符串對比
The relational operators work on strings. To see if two strings are equal:
> 關系運算符對于字符串來說也可用。比如可以看看兩個字符串是不是相等:
```Python
if word == 'banana':
print('All right, bananas.')
```
Other relational operations are useful for putting words in alphabetical order:
> 其他的關系運算符可以來把字符串按照字母表順序排列:
```Python
if word < 'banana':
print('Your word, ' + word + ', comes before banana.')
elif word > 'banana':
print('Your word, ' + word + ', comes after banana.')
else:
print('All right, bananas.')
```
Python does not handle uppercase and lowercase letters the same way people do. All the uppercase letters come before all the lowercase letters, so:
Your word, Pineapple, comes before banana.
> Python 對大小寫字母的處理與人類常規思路不同。所有大寫字母都在小寫字母之前,所以順序上應該是:
> Your word,然后是 Pineapple,然后才是 banana。
A common way to address this problem is to convert strings to a standard format, such as all lowercase, before performing the comparison. Keep that in mind in case you have to defend yourself against a man armed with a Pineapple.
> 一個解決這個問題的普遍方法是把字符串轉換為標準格式,比如都轉成小寫的,然后再進行比較。一定要記得哈,以免你遇到一個用 Pineapple 武裝著自己的家伙的時候手足無措。
## 8.11 Debugging 調試
When you use indices to traverse the values in a sequence, it is tricky to get the beginning and end of the traversal right. Here is a function that is supposed to compare two words and return True if one of the words is the reverse of the other, but it contains two errors:
> 使用索引來遍歷一個序列中的值的時候,弄清楚遍歷的開頭和結尾很不容易。下面這個函數用來對比兩個單詞,如果一個是另一個的倒序就返回真,但這個函數代碼中有兩處錯誤:
```Python
def is_reverse(word1, word2):
if len(word1) != len(word2):
return False
i = 0
j = len(word2)
while j > 0:
if word1[i] != word2[j]:
return False
i = i+1
j = j-1
return True
```
The first if statement checks whether the words are the same length. If not, we can return False immediately. Otherwise, for the rest of the function, we can assume that the words are the same length. This is an example of the guardian pattern in Section 6.8.
> 第一個 if 語句是檢查兩個詞的長度是否一樣。如果不一樣長,當場就返回假。對函數其余部分,我們假設兩個單詞一樣長。這里用到了守衛模式,在第6章第8節我們提到過。
i and j are indices: i traverses word1 forward while j traverses word2 backward. If we find two letters that don’t match, we can return False immediately. If we get through the whole loop and all the letters match, we return True.
If we test this function with the words “pots” and “stop”, we expect the return value True, but we get an IndexError:
> i 和 j 都是索引:i 從頭到尾遍歷單詞 word1,而 j 逆向遍歷單詞word2.如果我們發現兩個字母不匹配,就可以立即返回假。如果經過整個循環,所有字母都匹配,就返回真。
> 如果我們用這個函數來處理單詞『pots』和『stop』,我們希望函數返回真,但得到的卻是索引錯誤:
```Python
>>> is_reverse('pots', 'stop')
>>> is_reverse('pots', 'stop')
... File "reverse.py", line 15, in is_reverse if word1[i] != word2[j]: IndexError: string index out of range
```
For debugging this kind of error, my first move is to print the values of the indices immediately before the line where the error appears.
> 為了改正這個錯誤,第一步就是在出錯的那行之前先輸出索引的值。
```Python
while j > 0:
print(i, j) # print here
if word1[i] != word2[j]:
return False
i = i+1
j = j-1
```
Now when I run the program again, I get more information:
> 然后我再次運行函數,得到更多信息了:
```Python
>>> is_reverse('pots', 'stop')
>>> is_reverse('pots', 'stop')
0 4
... IndexError: string index out of range
```
The first time through the loop, the value of j is 4, which is out of range for the string 'pots'. The index of the last character is 3, so the initial value for j should be len(word2)-1.
If I fix that error and run the program again, I get:
> 第一次循環完畢的時候,j 的值是4,這超出了『pots』這個字符串的范圍了(譯者注:應該是0-3)。最后一個索引應該是3,所以 j 的初始值應該是 len(word2)-1。
```Python
>>> is_reverse('pots', 'stop')
>>> is_reverse('pots', 'stop')
0 3 1 2 2 1
True
```
This time we get the right answer, but it looks like the loop only ran three times, which is suspicious. To get a better idea of what is happening, it is useful to draw a state diagram. During the first iteration, the frame for is_reverse is shown in Figure 8.2.
> 這次我們得到了正確的結果,但似乎循環只走了三次,這有點奇怪。為了弄明白帶到怎么回事,我們可以畫一個狀態圖。在第一次迭代的過程中,is_reverse 的框架如圖8.2所示。
* * *

Figure 8.2: State diagram.
* * *
I took some license by arranging the variables in the frame and adding dotted lines to show that the values of i and j indicate characters in word1and word2.
Starting with this diagram, run the program on paper, changing the values ofi and j during each iteration. Find and fix the second error in this function.
> 我通過設置變量框架中添加虛線表明,i和j的值顯示在人物word1and word2拿許可證。
從這個圖上運行的程序,文件,更改這些值I和J在每一次迭代過程。發現并解決此函數中的二次錯誤。
## 8.12 Glossary 術語列表
object:
Something a variable can refer to. For now, you can use “object” and “value” interchangeably.
> 對象:一個值能夠指代的東西。目前為止,你可以把對象和值暫且作為一碼事來理解。
sequence:
An ordered collection of values where each value is identified by an integer index.
> 序列:一系列值的有序排列,每一個值都有一個唯一的整數序號。
item:
One of the values in a sequence.
> 元素:一列數值序列當中的一個值。
index:
An integer value used to select an item in a sequence, such as a character in a string. In Python indices start from 0.
> 索引:一個整數值,用來指代一個序列中的特定一個元素,比如在字符串里面就指代一個字符。在 Python 里面索引從0開始計數。
slice:
A part of a string specified by a range of indices.
> 切片:字符串的一部分,通過一個索引區間來取得。
empty string:
A string with no characters and length 0, represented by two quotation marks.
> 空字符串:沒有字符的字符串,長度為0,用兩個單引號表示。
immutable:
The property of a sequence whose items cannot be changed.
> 不可更改:一個序列中所有元素不能被改變的性質。
traverse:
To iterate through the items in a sequence, performing a similar operation on each.
> 遍歷:在一個序列中依次對每一個元素進行某種相似運算的過程。
search:
A pattern of traversal that stops when it finds what it is looking for.
> 搜索:一種遍歷的模式,找到要找的內容的時候就停止。
counter:
A variable used to count something, usually initialized to zero and then incremented.
> 計數:一種用來統計某種東西數量的變量,一般初始化為0,然后逐次遞增。
invocation:
A statement that calls a method.
> 方法調用:調用方法的語句。
optional argument:
A function or method argument that is not required.
> 可選參數:一個函數或者方法中有一些參數是可選的,非必需的。
## 8.13 Exercises 練習
### Exercise 1 練習1
Read the documentation of the string methods at [here](http://docs.python.org/2/library/stdtypes.html#string-methods). You might want to experiment with some of them to make sure you understand how they work. strip and replace are particularly useful.
> 閱讀 [這里](http://docs.python.org/2/library/stdtypes.html#string-methods)關于字符串的文檔。你也許會想要試試其中一些方法,來確保你理解它們的意義。比如 strip 和 replace 都特別有用。
The documentation uses a syntax that might be confusing. For example, in find(sub[, start[, end]]), the brackets indicate optional arguments. So sub is required, but start is optional, and if you include start, then end is optional.
> 文檔的語法有可能不太好理解。比如在find 這個方法中,方括號表示了可選參數。所以 sub 是必須的參數,但 start 是可選的,如果你包含了 start,end 就是可選的了。
### Exercise 2 練習2
There is a string method called count that is similar to the function in Section 8.7. Read the documentation of this method and write an invocation that counts the number of 'a's in 'banana'.
> 字符串有個方法叫 count,與咱們在8.7中寫的 count 函數很相似。 閱讀一下這個方法的文檔,然后寫一個調用這個方法的代碼,統計一下 banana 這個單詞中 a 出現的次數 。
### Exercise 3 練習3
A string slice can take a third index that specifies the “step size;” that is, the number of spaces between successive characters. A step size of 2 means every other character; 3 means every third, etc.
> 字符串切片可以使用第三個索引,作為步長來使用;步長的意思就是取字符的間距。一個步長為2的意思就是每隔一個取一個字符;3的意思就是每次取第三個,以此類推。
```Python
>>> fruit = 'banana'
>>> fruit = 'banana'
>>> fruit[0:5:2]
>>> fruit[0:5:2]
'bnn'
```
A step size of -1 goes through the word backwards, so the slice [::-1]generates a reversed string.
Use this idiom to write a one-line version of is_palindrome from Exercise 3.
> 步長如果為-1,意思就是倒序讀取字符串,所以[::-1]這個切片就會生成一個逆序的字符串了。
> 使用這個方法把練習三當中的is_palindrome寫成一個一行代碼的版本。
### Exercise 4 練習4
The following functions are all intended to check whether a string contains any lowercase letters, but at least some of them are wrong. For each function, describe what the function actually does (assuming that the parameter is a string).
> 下面這些函數都試圖檢查一個字符串是不是包含小寫字母,但他們當中肯定有些是錯的。描述一下每個函數真正的行為(假設參數是一個字符串)。
```Python
def any_lowercase1(s):
for c in s:
if c.islower():
return True
else:
return False
def any_lowercase2(s):
for c in s:
if 'c'.islower():
return 'True'
else:
return 'False'
def any_lowercase3(s):
for c in s:
flag = c.islower()
return flag
def any_lowercase4(s):
flag = False
for c in s:
flag = flag or c.islower()
return flag
def any_lowercase5(s):
for c in s:
if not c.islower():
return False
return True
```
### Exercise 5 練習5
A Caesar cypher is a weak form of encryption that involves “rotating” each letter by a fixed number of places. To rotate a letter means to shift it through the alphabet, wrapping around to the beginning if necessary, so ’A’ rotated by 3 is ’D’ and ’Z’ rotated by 1 is ’A’.
> 凱撒密碼是一種簡單的加密方法,用的方法是把每個字母進行特定數量的移位。對一個字母移位就是把它根據字母表的順序來增減對應,如果到末尾位數不夠就從開頭算剩余的位數,『A』移位3就是『D』,而『Z』移位1就是『A』了。
To rotate a word, rotate each letter by the same amount. For example, “cheer” rotated by 7 is “jolly” and “melon” rotated by -10 is “cubed”. In the movie 2001: A Space Odyssey, the ship computer is called HAL, which is IBM rotated by -1.
> 要對一個詞進行移位,要把每個字母都移動同樣的數量。比如『cheer』這個單詞移位7就是『jolly』,而『melon』移位-10就是『cubed』。在電影《2001 太空漫游》中,飛船的電腦叫 HAL,就是 IBM 移位-1。
Write a function called rotate_word that takes a string and an integer as parameters, and returns a new string that contains the letters from the original string rotated by the given amount.
> 寫一個名叫 rotate_word 的函數,接收一個字符串和一個整形為參數,返回將源字符串移位該整數位得到的新字符串。
You might want to use the built-in function ord, which converts a character to a numeric code, and chr, which converts numeric codes to characters. Letters of the alphabet are encoded in alphabetical order, so for example:
> 你也許會用得上內置函數 ord,它把字符轉換成數值代碼,然后還有個 chr 是用來把數值代碼轉換成字符。字母表中的字母都被編譯成跟字母表中同樣的順序了,所以如下所示:
```Python
>>> ord('c') - ord('a')
>>> ord('c') - ord('a')
2
```
Because 'c' is the two-eth letter of the alphabet. But beware: the numeric codes for upper case letters are different.
> c 是字母表中的第『2』個(譯者注:從0開始數哈)的位置,所以上述結果是2。但注意:大寫字母的數值代碼是和小寫的不一樣的。
Potentially offensive jokes on the Internet are sometimes encoded in ROT13, which is a Caesar cypher with rotation 13. If you are not easily offended, find and decode some of them. [Solution](http://thinkpython2.com/code/rotate.py).
> 網上很多有冒犯意義的玩笑都是用 ROT13加密的,也就是移位13的凱撒密碼。如果你不太介意,找一下這些密碼解密一下吧。[樣例代碼](http://thinkpython2.com/code/rotate.py).
- 介紹
- Think Python
- Chapter 0 Preface 前言
- Chapter 1 The way of the program 編程之路
- Chapter 2 Variables, expressions and statements 變量,表達式,語句
- Chapter 3 Functions 函數
- Chapter 4 Case study: interface design 案例學習:交互設計
- Chapter 5 Conditionals and recursion 條件循環
- Chapter 6 Fruitful functions 有返回值的函數
- Chapter 7 Iteration 迭代
- Chapter 8 Strings 字符串
- Chapter 9 Case study: word play 案例學習:單詞游戲
- Chapter 10 Lists 列表
- Chapter 11 Dictionaries 字典
- Chapter 12 Tuples 元組
- Chapter 13 Case study: data structure selection 案例學習:數據結構的選擇
- Chapter 14 Files 文件
- Chapter 15 Classes and objects 類和對象
- Chapter 16 Classes and functions 類和函數
- Chapter 17 Classes and methods 類和方法
- Chapter 18 Inheritance 繼承
- Chapter 19 The Goodies 額外補充