字符串是Python最常見的一種類型。通過在引號間包含字符的方式創建它。Python里單雙引號的作用是一致的。Python的對象類型里不存在字符型,一般用單個字符的字符串來使用。
Python的字符串是一種直接量或者說標量,Python解釋器在處理字符串時把它作為單一值并且不會包含其他Python類型的。Python的字符串也是不可改變類型。字符串里的字符可以通過切片操作訪問。
Python有3類字符串,通常意義字符串(str),Unicode字符串(unicode)和抽象類字符串(basestring)。實際上前兩者是最后一個的子類。而basestring是不能實例化的,如果試圖實例化,會得到以下的報錯信息。
>>> basestring('foo')Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: The basestring type cannot be instantiated
字符串的創建和賦值
創建一個字符串很簡單,可以直接創建,也可以用str()這樣的工廠函數創建。
>>> string1 = 'Pyhton'>>> string2 = "easy" #單雙引號等價>>> string3 = str(123)>>> string4 = str(range(4))>>> string1'Pyhton'>>> string2'easy'>>> string3'123'>>> string4'[0, 1, 2, 3]'
訪問字符串的字符和子串用直接索引或切片運算符
>>> aString = 'Hello World!'>>> aString[0]'H'>>> aString[1:5]'ello'>>> aString[6:]'World!'
改變字符串,用賦值的方式“更新”字符串。
跟數字類型一樣,字符串類型也是不可變的,每次更新都是創建新串。
刪除字符和字符串
因為字符串是不可變的,要刪除字符只能通過創建新串的方式實現。
>>> aString = 'Hello World!'>>> aString = aString[:3] + aString[4:]>>> aString'Helo World!'
而刪除字符串可以通過賦值一個空字符串或者del語句來清空或刪除一個字符串。
在大部分應用程序里,沒有必要顯示刪除字符串
字符串的大部分操作符是序列操作符部分,參看之前筆記。
下面是字符串和成員操作符的例子
Python的string模塊里有如下預定義的字符串
>>> import string>>> string.ascii_uppercase'ABCDEFGHIJKLMNOPQRSTUVWXYZ'>>> string.ascii_lowercase'abcdefghijklmnopqrstuvwxyz'>>> string.ascii_letters'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'>>> string.digits'0123456789'
我們將用這些東西來做一個Python有效標識符的小腳本
import stringalphas = string.letters + '_'nums = string.digitsPRint 'Welcome to the Identifier Checker v1.0'print 'Testees must be at least 2 chars long.'inp = raw_input('Indentifier to test?')if len(inp) > 1: if inp[0] not in alphas: print 'invalid: first symbol must be alphabetic' else: for otherChar in inp[1:]: if otherChar not in alphas + nums: print 'invalid: remaining symbols must be alphanumeric' break else: print 'okay as an identifier'
核心提示:性能
一般來說,從性能來考慮,把重復操作作為參數放到循環里是低效的
while i < len(myString): print 'character %d is:', myString[i]
這里把大部分操作浪費到重復計算myString上。如果保存這個值就可以更高效地循環。
length = len(myString)while i < length: print 'character %d is:', myString[i]
而上述例子中也存在重復的問題:
for otherChar in inp[1:]: if otherChar not in alphas + nums: ...
每次都進行一次合并操作是低效的。可以如下操作:
alphnums = alphas + numsfor otherChar in inp[1:]: if otherChar not in alphas + nums:
這個腳本是課本上的例程,并不完美,一是需要讓標識符的長度大于1,而是沒有考慮Python的關鍵字。所以為了解決這兩個問題,我寫了如下的腳本:
#! usr/bin/env pythonimport stringimport keyWordalphas = string.letters + '_'nums = string.digitsprint 'Welcome to the Identifier Checker v2.0'inp = raw_input('Indentifier to test:')if inp in keyword.kwlist: print 'It can''t be a keyword.'elif len(inp) > 0: if inp[0] not in alphas: print 'invalid: first symbol must be alphabetic' else: for otherChar in inp[1:]: if otherChar not in alphas + nums: print 'invalid: remaining symbols must be alphanumeric' break else: print 'okay as an identifier'else: print 'It can''t be None.'
Python可以用 + 連接字符串,除此以外還有一種習慣用法。
>>> abc = 'Hello''World'>>> abc'HelloWorld'
這種寫法可以將字符串分成幾部分來寫,可以在換行時使用。
這個寫法一樣可以混用兩種引號。
將普通字符串和Unicode字符串連接時,會轉換成Unicode字符串
只適用于字符串的操作符
1、格式化操作符 %
| 格式化字符 | 轉換方式 |
| %c | 轉換成字符(ASCII 碼值,或者長度為一的字符串) |
| %r | 優先用repr()函數進行字符串轉換 |
| %s | 優先用str()函數進行字符串轉換 |
| %d / %i | 轉成有符號十進制數 |
| %u | 轉成無符號十進制數 |
| %o | 轉成無符號八進制數 |
| %x/%X | (Unsigned)轉成無符號十六進制數(x/X 代表轉換后的十六進制字符的大小寫) |
| %e/%E | 轉成科學計數法(e/E 控制輸出e/E) |
| %f/%F | 轉成浮點數(小數部分自然截斷) |
| %g/%G | %e 和%f/%E 和%F 的簡寫 |
| %% | 輸出% |
這是只適用于字符串類型的操作符,和C語言中printf()的字符串格式化非常相似,包括符號都一致。
還有如下的格式化操作符輔助指令
| 符號 | 作用 |
| * | 定義寬度或者小數點精度 |
| - | 用做左對齊 |
| + | 在正數前面顯示加號( + ) |
| <sp> | 在正數前面顯示空格 |
| # | 在八進制數前面顯示零('0'),在十六進制前面顯示'0x'或者'0X'(取決于用的是'x'還是'X') |
| % | '%%'輸出一個單一的'%' |
| (var) | 映射變量(字典參數) |
| m.n | m 是顯示的最小總寬度,n 是小數點后的位數(如果可用的話) |
如下使用示例
>>> '%x'%108'6c'>>> '%X' %108'6C'>>> '%#X' % 108'0X6C'>>> '%f' % 1234.567890'1234.567890'>>> '%.2f' % 1234.567890'1234.57'>>> '%E' % 1234.567890'1.234568E+03'>>> '%e' % 1234.567890'1.234568e+03'>>> '%g' % 1234.567890'1234.57'>>> '%G' % 1234.567890'1234.57'>>> '%e' %(1111111111111)'1.111111e+12'>>> '%+d' % 4'+4'>>> '%+d' % -4'-4'>>> 'we are at %d%%' % 100'we are at 100%'>>> 'Your host is: %s' %'earth''Your host is: earth'>>> 'Host: %s/tPort: %d' % ('mars', 80)'Host: mars/tPort: 80'>>> num = 13>>> 'dec: %d/oct: %#o/hex: %#X' % (num, num, num)'dec: 13/oct: 015/hex: 0XD'>>> "MM/DD/YY = %02d/%02d/%d" % (2, 15, 67)'MM/DD/YY = 02/15/67'>>> w, p = 'Web', 'page'>>> 'http://xxx.yyy.zzz/%s/%s.html' % (w, p)'http://xxx.yyy.zzz/Web/page.html'
字符串格式化操作符還是個調試工具。所有的Python對象都有一個字符串表示形式
print語句自動為每個對象調用str()
2、字符串模板
字符串的缺點是它不是那么直觀,比如說用字典形式轉換出現遺漏轉換類型符號的錯誤。為了保證轉換正確,必須記住轉換類型參數。
新式的字符串模板的優勢是不用去記住所有的相關細節。而是用美元符號($)
Template對象有兩個方法,substitue()和safe_substitue().前者嚴謹,在key缺少的情況下它會報一個KeyError的異常,后者在缺少時,直接原封不動地顯示字符串。
>>> from string import Template>>> s = Template('There are ${howmany} ${lang} Quotation Symbols')>>> print s.substitute(lang='Python', howmany=3)There are 3 Python Quotation Symbols>>> print s.substiture(lang='Python')Traceback (most recent call last):File "<pyshell#3>", line 1, in <module>print s.substiture(lang='Python')AttributeError: 'Template' object has no attribute 'substiture'>>> print s.safe_substitute(lang='Python')There are ${howmany} Python Quotation Symbols
3、原始字符串操作符(r/R)
有些字符是特殊字符轉義字符,我們需要直接打印它們時會很麻煩。
所以Python提供了原始字符串,在原始字符串中,所有的字符只是字面意思,沒有其他意義。
>>> '/n''/n'>>> print '/n'>>> r'/n''//n'>>> print r'/n'/n
4、Unicode字符串操作符(u/U)
使用方法和原始字符操作符一致,將標準字符串對象轉成Unicode字符串對象。
內建函數
標準內建函數的cmp()不贅述
序列類型函數
len()
max()和min()
enumerate()
zip()
除了zip()函數以外,都在之前博文中講到了。zip()的作用如下:
>>> s, t = 'foa', 'obr'>>> zip(s, t)[('f', 'o'), ('o', 'b'), ('a', 'r')]
字符串類型函數
raw_input()
用給定字符串提示用戶輸入并將輸入返回。
str()和unicode()
不贅述
chr(),unichr()和ord()
chr()是輸入一個范圍在0到255的整數參數,返回一個對應的字符串。
unichr()是返回Unicode字符,范圍也更大。
ord()是chr()的配對函數,給字符返回ascii參數
方法 | 描述 |
string.capitalize() | 把字符串的第一個字符大寫 |
string.center(width) | 返回一個原字符串居中,并使用空格填充至長度 width 的新字符串 |
string.count(str, beg=0, end=len(string)) | 返回 str 在 string 里面出現的次數,如果 beg 或者 end 指定則返回指定范圍內 str 出現的次數 |
string.decode(encoding='UTF-8', errors='strict') | 以 encoding 指定的編碼格式解碼 string,如果出錯默認報一個 ValueError 的 異 常 , 除 非 errors 指 定 的 是 'ignore' 或 者'replace' |
string.encode(encoding='UTF-8', errors='strict') | 以 encoding 指定的編碼格式編碼 string,如果出錯默認報一個ValueError 的異常,除非 errors 指定的是'ignore'或者'replace' |
string.endswith(obj, beg=0, end=len(string)) | 檢查字符串是否以 obj 結束,如果beg 或者 end 指定則檢查指定的范圍內是否以 obj 結束,如果是,返回 True,否則返回 False. |
string.expandtabs(tabsize=8) | 把字符串 string 中的 tab 符號轉為空格,默認的空格數 tabsize 是 8. |
string.find(str, beg=0, end=len(string)) | 檢測 str 是否包含在 string 中,如果 beg 和 end 指定范圍,則檢查是否包含在指定范圍內,如果是返回開始的索引值,否則返回-1 |
string.index(str, beg=0, end=len(string)) | 跟find()方法一樣,只不過如果str不在 string中會報一個異常. |
string.isalnum() | 如果 string 至少有一個字符并且所有字符都是字母或數字則返 回 True,否則返回 False |
string.isalpha() | 如果 string 至少有一個字符并且所有字符都是字母則返回 True, 否則返回 False |
string.isdecimal() | 如果 string 只包含十進制數字則返回 True 否則返回 False. |
string.isdigit() | 如果 string 只包含數字則返回 True 否則返回 False. |
string.islower() | 如果 string 中包含至少一個區分大小寫的字符,并且所有這些(區分大小寫的)字符都是小寫,則返回 True,否則返回 False |
string.isnumeric() | 如果 string 中只包含數字字符,則返回 True,否則返回 False |
string.isspace() | 如果 string 中只包含空格,則返回 True,否則返回 False. |
string.istitle() | 如果 string 是標題化的(見 title())則返回 True,否則返回 False |
string.isupper() | 如果 string 中包含至少一個區分大小寫的字符,并且所有這些(區分大小寫的)字符都是大寫,則返回 True,否則返回 False |
string.join(seq) | Merges (concatenates)以 string 作為分隔符,將 seq 中所有的元素(的字符串表示)合并為一個新的字符串 |
string.ljust(width) | 返回一個原字符串左對齊,并使用空格填充至長度 width 的新字符串 |
string.lower() | 轉換 string 中所有大寫字符為小寫. |
string.lstrip() | 截掉 string 左邊的空格 |
string.partition(str) | 有點像 find()和 split()的結合體,從 str 出現的第一個位置起,把 字 符 串 string 分 成 一 個 3 元 素 的 元 組 (string_pre_str,str,string_post_str),如果 string 中不包含str 則 string_pre_str == string. |
string.replace(str1, str2, num=string.count(str1)) | 把 string 中的 str1 替換成 str2,如果 num 指定,則替換不超過 num 次. |
string.rfind(str, beg=0,end=len(string) ) | 類似于 find()函數,不過是從右邊開始查找. |
string.rindex( str, beg=0,end=len(string)) | 類似于 index(),不過是從右邊開始. |
string.rjust(width) | 返回一個原字符串右對齊,并使用空格填充至長度 width 的新字符串 |
string.rpartition(str) | 類似于 partition()函數,不過是從右邊開始查找. |
string.rstrip() | 刪除 string 字符串末尾的空格. |
string.split(str="", num=string.count(str)) | 以 str 為分隔符切片 string,如果 num有指定值,則僅分隔 num 個子字符串 |
string.splitlines(num=string.count('/n')) | 按照行分隔,返回一個包含各行作為元素的列表,如果 num 指定則僅切片 num 個行. |
string.startswith(obj, beg=0,end=len(string)) | 檢查字符串是否是以 obj 開頭,是則返回 True,否則返回 False。如果beg 和 end 指定值,則在指定范圍內檢查. |
string.strip([obj]) | 在 string 上執行 lstrip()和 rstrip() |
string.swapcase() | 翻轉 string 中的大小寫 |
string.title() | 返回"標題化"的 string,就是說所有單詞都是以大寫開始,其余字母均為小寫(見 istitle()) |
string.translate(str, del="") | 根據 str 給出的表(包含 256 個字符)轉換 string 的字符, 要過濾掉的字符放到 del 參數中 |
string.upper() | 轉換 string 中的小寫字母為大寫 |
string.zfill(width) | 返回長度為 width 的字符串,原字符串 string 右對齊,前面填充0 |
以上的函數不寫使用例程了。數量很多,很多很有用。
字符串的獨特特性
特殊字符串和控制字符
特殊字符串大多是反斜杠轉義的,像普通字符串一樣存儲到Python的字符串中。
因為Python和C語言不同,結束并不是NUL(/000),NUL和其他反斜杠轉義符沒有區別,所以一個字符串中可以在任意位置出現NUL
三引號控制字符串。用三引號括起來的字符串可以跨越多行,使控制簡單:
>>> foo = '''abcd efg'''>>> foo'abcd/n efg'>>> print fooabcdefg
字符串關鍵點總結
引號分隔的一些字符(單雙三引號)
不可分字符類型
字符串格式化操作符(%)提供類似printf()的功能
三引號
原始字符串操作符(r/R)
Python字符串不以NUL或者'/0'結束
新聞熱點
疑難解答