Python-字串

N1rv2na發表於2024-07-01

字串

1. 字串字面量

  • 單引號:'spa"m'
  • 雙引號:"spa'm"
  • 三引號:'''...spam...''', """...spam..."""
  • 轉義序列:"s\tp\na\0m"
  • 原始字串:r"C:\new\test.spm"
  • 位元組字面量:b'spx01am'
  • Unicode字面量:u'eggs\u0020spam'

1.1 單引號和雙引號字串是相同的

在Python字串中,單引號和雙引號字元是可以互換的。字串字面量包圍在兩個單引號和兩個雙引號中,將返回相同型別的物件。

>>> 'shrubbery', "shrubbery"
('shrubbery', 'shrubbery')

支援單引號和雙引號字串的原因是,可以不使用反斜槓轉義就可以在一種引號的字串中包含另一種引號:

>>> 'knight"s', "knight's"
('knight"s', "knight's")

儘量選擇在字串左右使用單引號包圍,閱讀起來稍稍簡單。

Python會在表示式中自動拼接相鄰的字串字面量,當然也可以在兩個字串字面量之間使用加號(+)來拼接:

>>> "Meaning " 'of' " Life"
'Meaning of Life'
>>> "Meaning " + 'of' + " Life"
'Meaning of Life'

在字串之間新增一個逗號會建立元組而不是字串:

>>> 'knight\'s', "knight\"s"  
("knight's", 'knight"s')
# 在單引號(或雙引號)包圍的字串中如果要使用單引號(或雙引號)需要使用反斜槓轉義

1.2 轉義序列代表特殊字元

反斜槓用來引入特殊的字元編碼,稱為轉義序列。轉義序列能夠讓我們再字串中嵌入不容易透過鍵盤輸入的字元。字元\以及字串字面量中在它後面的一個或多個字元,在生成的字串物件中會被單個字元所替代,這個字元擁有透過轉義序列定義的二進位制值:

>>> s = 'a\nb\tc'  # \n表示換行符,\t表示製表符
>>> print(s)
a
b       c
>>> len(s)  # 轉義序列是單個字元
5

字串反斜槓字元

一些轉義序列允許在字串的字元之間嵌入絕對二進位制數值:

>>> s = 'a\0b\0c'
>>> s
'a\x00b\x00c'

在Python中像\0這樣的空字元不會像C語言一樣去結束一個字元。

不管如何指定不可列印的字元,在Python中都以十六進位制顯示:

>>> s = '\001\002\x03'
>>> s
'\x01\x02\x03'

如果Python認為\後的字元不是有效的轉義編碼,那麼它會直接在生成的字串中保留反斜槓

然而不應該依賴此行為,如果希望使用反斜槓應當明確使用\\

>>> x = "C:\py\code"
>>> x
'C:\\py\\code'

1.3 原始字串阻止轉義

引入跳脫字元後,需要特別注意含有反斜槓的字串:

myfile = open('C:\new\text.dat', 'w')

這裡明明想要開啟C盤下new目錄下的text.dat檔案,然而由於這裡含有反斜槓,並且反斜槓後的字元都是有效的轉義編碼(\n, \t),因此Python會認為這裡想要開啟一個名為C:(換行符)ew(製表符)ext.dat的檔案。

如果字母r出現在字串的第一個引號的前面,那麼這一個字串就是原始字串(raw string),原始字串將關閉轉義機制

原始字串會將反斜槓當做字面量,原始字串與輸入的完全一致。

myfile = open(r'C:\new\text.dat', 'w')

myfile = open('C:\\new\\text.dat', 'w')
>>> x = "C:\new\text.dat"
>>> x
'C:\new\text.dat'
>>> path = r"C:\new\text.dat"
>>> path
'C:\\new\\text.dat'
>>> print(path)
C:\new\text.txt
>>> len(path)
15

注意:Python會自動在Windows和Unix的路徑中使用斜杆/表示字串路徑:

myfile = open('C:/new/text.tat')  # 在windows中可以用左斜杆表示字串路徑

儘管原始字串可以阻止轉義,但原始字串不能以單個反斜槓結尾,因為反斜槓會轉義後面的引號字元,即r"...\"不是一個有效的字串字面量。如果想要使用單個反斜槓結束的原始字串,可以使用如下方式:

>>> s1 = r'1\n\tc\\'
>>> s1
'1\\n\\tc\\\\'
>>> len(s1)
8
>>> s1[:-1]
'1\\n\\tc\\'
>>> s2 = r'1\n\tc' + '\\'
>>> s2
'1\\n\\tc\\'

1.4 三引號編寫多行塊字串

Python中還有一種三引號的字串字面量格式,有時候被稱作塊字串。塊字串以三個引號(單引號或者雙引號都可以)開始,並且緊跟任意行數的文字,並且以與開始時相同的三個引號結尾。

>>> mantra = """Always look
...  on the bright
... side of life."""
>>>
>>> mantra
'Always look\n on the bright\nside of life.'
>>> print(mantra)
Always look
 on the bright
side of life.

Python會把所有在三引號內的文字收集到一個單獨的多行字串中,並且在程式碼行轉折處嵌入換行符(\n),注意輸入的是什麼得到的塊字串就是什麼,比如上面的字面量中,第二行開頭有空格,第三行就沒有。

塊字串會保留所有包圍的文字,包括程式碼右側的註釋:

>>> menu = """spam       # comments here added to string!
... eggs                 # ditto
... """
>>> menu
'spam       # comments here added to string!\neggs                 # ditto\n'

三引號字串在程式需要輸入多行文字的時候很有用,比如在Python中嵌入HTML、XML或JSON程式碼。

三引號字串也常用於文件字串。

三行字串也可用於廢除大段的程式碼,這比每行之前加上#號要容易得多。

2. 實際應用中的字串

2.1 基礎操作

>>> len('abc')     # len函式將返回字串的長度
3
>>> 'abc' + 'def'  # +運算子,拼接兩個字串
'abcdef'
>>> 'Ni!' * 4      # *運算子,重複多個字串
'Ni!Ni!Ni!Ni!'

len內建函式返回字串(或其他任何擁有長度的物件)的長度,使用+相加兩個字串物件會建立一個新的字串物件,其內容是兩個字串物件的內容相連,使用*重複就像在字串後再增加一定數量的自身。

注意:這裡的+*運算子已經是過載過的,這裡的+*運算子的運算物件必須是字串,不能混合字串和數字,例如'abc' + 9將丟擲異常。

可以使用for語句在迴圈中對字串進行迭代,並使用in表示式運算子對字元和子字串進行成員關係測試。

>>> for c in myjobs: print(c, end=' ')
...
h a c k e r
>>> "k" in myjobs
True
>>> "z" in myjobs
False
>>> 'hack' in 'hacker'
True

2.2 索引與分片

字串中的字元可以透過索引來獲取,python中的偏移量是從0開始的,以比字串長度小1的偏移量結束。Python還支援使用負偏移量,從技術上說,一個負偏移量會與這個字串的長度相加,從而得到一個正的偏移量,可以把負偏移量看作從結尾處反向計數。

>>> S = 'spam'
>>> S[0], S[-2]
('s', 'a')

字串正負索引

分片是索引的一種擴張形式,返回的是一個完整片段而不是一個單獨元素。

當使用一對以冒號分隔的偏移量(s[1:3])對字串這樣的序列物件進行分片時,Python將返回一個新的物件,其中包含了由這對索引所標識的連續的內容,左邊的偏移量作為下邊界(包含下邊界在內),而右邊的偏移量作為上邊界(不包含上邊界在內)。即Python將獲取從下邊界直到但不包括上邊界的所有元素,並返回一個包含所有獲取元素的新物件。如果左邊界的偏移量省略的話,預設值為0,如果右邊界的偏移量省略的話,預設值為字串的長度。

分片(S[i:j])提取序列的連續部分:

S[1:3]表示提取出序列中從偏移量為1直到但是不包括偏移量為3之間的所有元素;

S[1:]得到除了第一個元素以外的全部元素(省略上邊界的情況下,預設上邊界的值為序列長度);

S[:-1]獲取除最後一個元素以外的所有元素(省略下邊界的情況下,下邊界的值預設為0)。

S[:]獲取從偏移量為0直到末尾的所有元素,實現了對S的頂層複製。

擴充套件分片

分片表示式可以增加一個可選的索引值作為步長,分片的完整形式變成了X[I:J:K],它表示“提取物件X中的所有物件,從偏移量I直到偏移量J-1,每隔K個元素索引一次”其中步長K如果省略的話,預設值為+1。

例如X[1:10:2]會取出X中,偏移量為1至9之間,每隔一個元素的所有元素,即收集位於偏移量1、3、5、7、9出的元素。X[::2]由於上下邊界值省略,預設值為0和序列的長度,因此會取出序列中從頭到尾每隔一個元素的所有元素。

>>> S = 'abcdefghijklmnop'
>>> S[1:10:2]
'bdfhj'
>>> S[::2]
'acegikmo'

步長也可以使用負數來以相反的順序(從右往左)來獲取元素。

>>> S = 'hello'
>>> S[::-1]  # S[::-1]可以將字串反轉
'olleh'

注意:使用負數步長時,前面兩個邊界的意義實際上進行了反轉:

>>> S = 'abcdefg'
>>> S[5:1:-1]
'fedc'
# S[5:1:-1]表示從右往左來獲取元素,左邊界為偏移量5,右邊界為偏移量1,實際上獲取了偏移量為5、4、3、2的元素

分片實際上是使用一個分片物件進行索引:

>>> 'spam'[1:3]
'pa'
>>> 'spam'[slice(1, 3)]
'pa'
>>> 'spam'[::-1]
'maps'
>>> 'spam'[slice(None, None, -1)]
'maps'

2.3 字串轉換工具

在Python中不能夠相加字串和數字:

>>> '42' + 10
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str

int函式可以將字串轉換為整數,float函式可以將字串轉換為浮點數;

str函式可以將數字轉換為字串,repr函式也可以將數字轉換為字串,但repr函式返回可作為程式碼的字串物件

str函式和repr函式

str和repr函式都會把任意的物件轉換為字串表示,但是repr(預設的互動式命令中顯示的就是repr)會產生看起來更像程式碼的結果,而str(print列印的就是str)轉換為對使用者更加友好的形式。物件同時擁有這兩種方式,str用於一般用途,而repr帶有額外細節。

>>> repr('spam')
"'spam'"
>>> str('spam')
'spam'

字串程式碼轉換

ord函式可以將單個字元轉換為其底層的ASCII碼值,chr函式則會將ASCII碼轉換為對應的字元。

>>> ord('S')
83
>>> chr(83)
'S'
>>> S = '5'
>>> chr(ord(S) + 1)
'6'
# 如下程式碼可以將二進位制字串轉換為整數
>>> B = '1101'
>>> I = 0
>>> while B!= '':
...     I = I * 2 + ord(B[0]) - ord('0')
...     B = B[1:]
...
>>> I
13
# 當然也可以使用int函式將二進位制字串轉換為整數
>>> int('1101', 2)
13
>>> bin(13)
'0b1101'

2.4 修改字串

字串是不可變序列,不能在字串的原位置上修改:

>>> S = 'spam'
>>> S[0] = 'x'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

若要改變字串,通常需要利用拼接、分片來建立並賦值一個新的字串

>>> S = 'x' + S[1:]
>>> S
'xpam'
>>> S = S + 'SPAM'
>>> S
'xpamSPAM'

注意,每修改一次字串都會產生一個新的字串物件,Python會自動對不再使用的字串物件自動進行垃圾回收,所以新的字串物件會重用之前的字串物件所佔的空間。

2.5 字串方法

除了表示式運算子之外,Python字串還提供了一系列更為複雜的文字處理任務的方法。在Python中,表示式和字串可以在不同的型別直接工作,但是方法通常特定於物件型別才能使用。

方法呼叫語法

方法呼叫同時結合了一次屬性獲取和一次函式呼叫操作。

  • 屬性獲取object.attribute獲取物件object中attribute屬性的值
  • 呼叫表示式function(arguments)呼叫函式function的程式碼,向其傳遞零個或多個逗號分隔的引數argument物件,並且返回函式function執行的結果

方法呼叫語法:object.method(arguments)

Python首先讀取物件object的方法method,然後呼叫它,傳遞物件object和引數arguments。

>>> S = 'spam'
>>> result = S.find('pa')
>>> result
1

字串方法示例:修改字串

替換子字串

替換子字串,可以透過分片和拼接來實現:

>>> S = 'spammy'
>>> S = S[:3] + 'xx' + S[5:]
>>> S
'spaxxy'

也可以透過replace方法來替換子字串:

>>> 'aa$bb$cc$dd'.replace('$', 'SPAM') # replace substr '$' with 'SPAM'
'aaSPAMbbSPAMccSPAMdd'

replace方法的引數是最始的子串和用於替換最初的子串的新子串,replace方法會對字串進行全域性搜尋並替換。

注意:字串方法每次都會返回一個新的字串物件,因為字串是不可變的,因此replace方法並沒有真正在原處修改替換子字串!

replace預設會進行全域性替換(即替換所有查詢到的原子字串為新的子字串),也可以指定替換次數:

>>> S = 'xxxxSPAMxxxxSPAMxxxx'
>>> S.replace('SPAM', 'EGGS')  # 替換所有
'xxxxEGGSxxxxEGGSxxxx'
>>> S.replace('SPAM', 'EGGS', 1)  # 替換一次
'xxxxEGGSxxxxSPAMxxxx'
查詢子字串

find方法可以查詢並返回字串中某個子串出現處的偏移量,如果未找到該子串時則返回-1。子字串查詢就像是in表示式,只不過find方法會返回子串所在的位置。

>>> S = 'xxxxSPAMxxxxSPAMxxxx'
>>> where = S.find('SPAM')
>>> where
4

rfind方法作用相同,不過是從右到左查詢子串。

index方法類似find方法,但是在找不到子串時會丟擲ValueError異常。

>>> S = 'xxxxSPAMxxxxSPAMxxxx'
>>> S.index('SPAM')
4
>>> S.index('egg')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: substring not found

rindex方法作用相同,不過是從右到左查詢子串。

字串合併

字串拼接和replace方法每次呼叫都會生成新的字串物件,雖然字串是不可變的,但是如果想要對字串進行原位置的修改,可以先將字串轉換成一個支援原位置修改的物件,之後再對轉換後的物件進行合併

>>> S = 'spammy'
>>> L = list(S)
>>> L
['s', 'p', 'a', 'm', 'm', 'y']
>>> L[3] = 'x'
>>> L[4] = 'x'
>>> L
['s', 'p', 'a', 'x', 'x', 'y']
>>> S = ''.join(L)  # 以分隔符為空將列表L中的字串連線在一起
>>> S
'spaxxy'

join方法可以將列表(或其他可迭代物件)中的字串連線在一起,並且在元素間用分隔符分隔開。

>>> 'SPAM'.join(['eggs', 'sausage', 'ham', 'toast'])
'eggsSPAMsausageSPAMhamSPAMtoast'
字串分隔

字串的split方法可以將一個字串按指定的分隔符分割成一系列子串並返回所生成的子串列表。

split方法預設按空白符(空格、製表符、換行符)來進行分割。

>>> line = "aaa bbb ccc"
>>> cols = line.split()
>>> cols
['aaa', 'bbb', 'ccc']

split可以指定具體的分隔符。

>>> line = 'bob,hacker,40'
>>> line.split(',')
['bob', 'hacker', '40']
>>> line = "i'mSPAMaSPAMlumberjack"
>>> line.split('SPAM')  # 分割符也可以為多個字元
["i'm", 'a', 'lumberjack']

rsplit方法作用相同,不過是從右到左分割字串。

字串的partition方法和rpartition方法同樣可以分割字串,不過partition方法會在分隔符首次出現的位置拆分字串,而rpartition方法則會在分隔符最後一次出現的位置拆分字串,兩者都將返回一個 3 元組,其中包含分隔符之前的部分、分隔符本身,以及分隔符之後的部分。 如果分隔符未找到,則返回的 3 元組中包含兩個空字串以及字串本身。

>>> line = 'bob,hacker,40'
>>> line.partition(',')
('bob', ',', 'hacker,40')
>>> line.rpartition(',')
('bob,hacker', ',', '40')
字串大小寫

capitalize方法可以將字串的首個字母轉換為大寫,其餘為小寫。

>>> line = "the knight who say Ni!"
>>> line.capitalize()
'The knight who say ni!'

swapcase方法可以將字串中的大寫字母轉換為小寫,將小寫字母轉換為大寫:

>>> line.swapcase()
'THE KNIGHT WHO SAY nI!'

title方法返回字串的標題版本,其中每個單詞第一個字母為大寫,其餘字母為小寫:

>>> line.title()
'The Knight Who Say Ni!'

upper方法可以將字串中的所有字母都轉換為大寫,lower方法則可以將字串中的所有字母都轉換為小寫:

>>> line.upper()
'THE KNIGHT WHO SAY NI!'
>>> line.lower()
'the knight who say ni!'
字串去空

strip方法可以去除字串的前導和末尾的空白字元:

>>> '   spacious   '.strip()
'spacious'

strip方法也可以指定要移除的字元chars,此時strip將會移除字串的前導和末尾的所有chars字元,直至遇到第一個不包含在chars中的字元。

>>> 'www.example.com'.strip('cmowz.')
'example'

lstriprstrip方法的用法與strip相同,不過lstrip方法只移除前導空白符或指定字元,而rstrip方法則只移除末尾的空白符或指定字元。

>>> '   spacious   '.lstrip()
'spacious   '
>>> >>> 'www.example.com'.lstrip('cmowz.')
'example.com'
>>> '   spacious   '.rstrip()
'   spacious'
>>> >>> 'www.example.com'.rstrip('cmowz.')
'www.example'
字串字元判斷
  • isalpha方法:如果字串中的所有字元都是字母或數字且至少有一個字元,則返回True, 否則返回False
  • isascii方法:如果字串為空或字串中的所有字元都是 ASCII ,返回True ,否則返回False
  • isdecimal方法:如果字串中的所有字元都是十進位制字元且該字串至少有一個字元,則返回True,否則返回False
  • isdigit方法:如果字串中的所有字元都是數字,並且至少有一個字元,返回True,否則返回False
  • isidentifier方法:如果字串是有效的識別符號,返回True,否則返回False
  • islower方法:如果字串中至少有一個區分大小寫的字元,並且此類字元均為小寫則返回True,否則返回False
  • isnumeric方法:如果字串中至少有一個字元且所有字元均為數值字元則返回True,否則返回 False
  • isspace方法:如果字串中只有空白字元且至少有一個字元則返回True,否則返回False
  • istitle方法:如果字串中至少有一個字元且為標題字串則返回True,否則返回False
  • issupper方法:如果字串中至少有一個區分大小寫的字元且此類字元均為大寫則返回True,否則返回False
字串前字尾
  • startswith方法:如果字串以指定的prefix開始則返回True,否則返回False
  • endswith方法:如果字串以指定的prefix結尾則返回True,否則返回False
>>> line = "the knight who say Ni!"
>>> line.startswith('the')
True
>>> line.endswith('Ni!')
True

2.6 字串格式化表示式

如今的Python中的字串格式化可以用兩種形式實現:

  • 字串格式化表示式'...%s...' % (values)
  • 字串格式化方法呼叫'...{}...'.format(values)

格式化字串表示式基礎

格式化字串:

1.在%運算子的左側放置一個需要進行格式化的字串,這個字串帶有一個或多個內嵌的轉換目標,都以%開頭(如%d);

2.在%運算子右側放置一個(或多個,內嵌在元組中的)物件,這些物件將會插入到想讓Python進行格式化的左側的字串中,並替換一個(或多個)轉換目標;

>>> 'The knight who say %s!' % exclamation
'The knight who say Ni!'
>>> 'That is %d %s bird!' % (1, 'dead')
'That is 1 dead bird!'

注意:當只有一個替換標記時,則右側的%運算子後直接跟想要替換的值即可;當有多個替換標記時,則需要在右側%運算子後跟多個想要替換的值的元組。

高階格式化表示式語法

字串格式化型別碼:

字串格式化型別碼

字串格式化型別碼語法:%[(keyname)][flags][width][.precision]typecode

  • (keyname):為索引在表示式右側使用的字典提供鍵名稱:
>>> '%(language)s has %(number)d quote types.' % {'language': 'Python', 'number': 2}
'Python has 2 quote types.'
  • flags:特殊轉換標識,主要有以下標識:
    • '0'——轉換將為數字值填充零字元;(需配合width使用)
    • '-'——轉換值將靠左對齊;
    • ' '(空格)——符號位轉換產生的整數前將留出一個空格;
    • '+'——轉換將為數字值新增正負號字元
>>> 'There is %03d birds' % 2
'There is 002 birds'
>>> 'There is %-3d birds' % 2
'There is 2   birds'
>>> 'There is % d birds' % 2
'There is  2 birds' # 2前多了一個空格
>>> 'There is %+d birds' % 2
'There is +2 birds'
  • width:為被替換的文字給出總的最小字元寬度
>>> 'There is %3d birds' % 2
'There is   2 birds' # 2小於最小字元寬度3,不足的用空格補齊
>>> 'There is %3d birds' % 1000
'There is 1000 birds' # 1000大於最小字元寬度3,此時寬度不生效
  • .precision:為浮點數字設定小數點後顯示的位數(即精度)
>>> pi = 3.1415926
>>> 'pi approximatelly equals %.2f' % pi
'pi approximatelly equals 3.14'
>>> '%e | %E | %f | %g' % (x, x, x, x)
'1.234568e+00 | 1.234568E+00 | 1.234568 | 1.23457'
>>> '%-6.2f | %05.2f | %+06.1f' % (x, x, x)
'1.23   | 01.23 | +001.2'

2.7 字串格式化方法呼叫

字串格式化方法基礎

字串格式化方法是字串方法,它使用主體字串作為模板,並且接受任意多個引數,用來表示將要根據模板替換的值。

主體字串中,花括號透過位置(如{1})、關鍵字(如{food})或者相對位置(如{})來制定替換及要插入的引數。

>>> template = '{0}, {1} and {2}'
>>> template.format('spam', 'ham', 'eggs')
'spam, ham and eggs'
>>> template = '{matto}, {pork} and {food}'
>>> template.format(matto='spam', pork='ham', food='eggs')
'spam, ham and eggs'
>>> template = '{matto}, {0} and {food}'
>>> template.format('ham', matto='spam', food='eggs')
'spam, ham and eggs'
>>> template = '{} , {} and {}'
>>> template.format('spam', 'ham', 'eggs')
'spam , ham and eggs'
>>> template = '%s , %s and %s'
>>> template % ('spam', 'ham', 'eggs')
'spam , ham and eggs'
>>> template = '%(matto)s, %(pork)s and %(food)s'
>>> template % dict({'matto': 'spam', 'pork': 'ham', 'food': 'eggs'})
'spam, ham and eggs'

新增鍵、屬性和偏移量

像%格式化表示式一樣,格式化字串可以指定物件屬性和字典鍵,方括號指定字典鍵,而點表示透過位置或關鍵字所引用的元素的物件屬性

>>> import sys
>>> 'My {1[kind]} runs {0.platform}'.format(sys, {'kind': 'laptop'})
'My laptop runs win32'
>>> 'My {map[kind]} runs {sys.platform}'.format(sys=sys, map={'kind': 'laptop'})
'My laptop runs win32'
>>> data = dict(platform=sys.platform, kind='laptop')
>>> 'My {kind:<8} runs {platform:>8}'.format(**data)
'My laptop   runs    win32'
# **data把字典data解包為一組類似"name=value"的關鍵字引數

格式化字串中的方括號可以指定列表的偏移量來執行索引,但是隻有單個正偏移量才能在格式化字串的語法中有效,提供想要指定負偏移量或者分片或使用任意表示式的結果,則必須在格式化字串之外先執行表示式:

>>> somelist = list('SPAM')
>>> somelist
['S', 'P', 'A', 'M']
>>> 'first={0[0]}, third={0[2]}'.format(somelist)
'first=S, third=A'
>>> 'first={0[0]}, third={0[-1]}'.format(somelist)  # 負索引將會出錯
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list indices must be integers or slices, not str
>>> 'first={0}, last={1}'.format(somelist[0], somelist[-1]) # format中指定具體的列表元素時才能使用負索引
'first=S, last=M'
>>> parts = somelist[0], somelist[-1], somelist[1:3]
>>> 'first={0}, last={1}, middle={2}'.format(*parts)
"first=S, last=M, middle=['P', 'A']"
# 這裡使用*parts來解包一個元組的項作為單獨的函式引數

高階格式化方法語法

對於格式化方法,可以在可能為空的替換目標的標識碼之後使用一個冒號,後面跟著可以指定欄位大小、對齊方式和特定型別編碼的格式化說明符。

高階格式化方法語法:{fieldname component !conversionflag :formatspec}

  • fieldname是標識替換目標的一個可選的數字或者關鍵字,可為空
  • component是類似'.attribute''[index]'的字串,用來獲取引數的屬性或者索引值
  • conversionflag如果出現則以!開始,後面跟著r、s或者a,在這個值上分別呼叫repr、str或者ascii內建函式
  • formatspec如果出現則以:開始,後面格子文字,指定了如何表示該值,包括欄位寬度、對齊方式、補零、小數精度等細節,以一個可選的資料型別碼結束

formatspec書寫格式:[[fill]align][sign][#][width][,][.precision][typecode]

  • fill可以是除{或}以外的任意填充字元,align可以是<、>、=或^,分別表示左對齊、右對齊、符號字元後的填充、或者居中對齊
  • sign可以是+、-或者空格
  • width表示被替換文字的最小字元寬度
  • ,(逗號)選項請求一個逗號表示千分位分隔符
  • .precision表示浮點數的顯示精度
  • typecode則是資料型別碼,與%格式化字串表示式類似,如d表示整數、f表示浮點數、s表示字串
>>> '{0:10} = {1:10}'.format('spam', 123.4567)
'spam       =   123.4567'
>>> '{0:>10} = {1:<10}'.format('spam', 123.4567)
'      spam = 123.4567  '
>>> import sys
>>> '{0.platform:>10} = {1[kind]:<10}'.format(sys, {'kind': 'laptop'})
'     win32 = laptop    '

也可以省略引數索引,不過會降低程式碼的可讀性:

>>> '{:10} = {:10}'.format('spam', 123.4567)
'spam       =   123.4567'
>>> '{:>10} = {:<10}'.format('spam', 123.4567)
'      spam = 123.4567  '
>>> import sys
>>> '{.platform:>10} = {[kind]:<10}'.format(sys, {'kind': 'laptop'})
'     win32 = laptop    '

字串格式化方法呼叫的浮點數格式化與字串格式化表示式類似:

>>> '{0:e}, {1:.3e}, {2:g}'.format(3.14159, 3.14159, 3.14159)
'3.141590e+00, 3.142e+00, 3.14159'
>>> '{0:f}, {1:.2f}, {2:+06.2f}'.format(3.14159, 3.14159, 3.14159)
'3.141590, 3.14, +03.14'

字串格式化方法也支援十六進位制、八進位制和二進位制格式:

>>> '{0:x}, {1:o}, {2:b}'.format(255, 255, 255)
'ff, 377, 11111111'
>>> bin(255), int('11111111', 2), 0b11111111
('0b11111111', 255, 255)
>>> hex(255), int('ff', 16), 0xff
('0xff', 255, 255)
>>> oct(255), int('377', 8), 0O377
('0o377', 255, 255)

python還引入了一種新的內建format函式,可以用來格式化單獨的一項:

>>> '{0:.2f}'.format(1.2345)
'1.23'
>>> '%.2f' % 1.2345
'1.23'
>>> format(1.2345, '.2f')
'1.23'

字串格式化表示式 vs 字串格式化方法

  • 字串格式化方法有一些額外的功能,而字串格式化表示式不支援,如字串格式化方法有二進位制型別碼和千分位分組:
>>> '{0:b}'.format(2 ** 16 - 1)
'1111111111111111'
>>> '%b' % (2 ** 16 - 1)  # 格式化字串表示式不支援二進位制型別符
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: unsupported format character 'b' (0x62) at index 1
>>> '{0:,d}'.format(999999999)
'999,999,999'
>>> '%,d' % 999999999  # 格式化字串表示式不支援千分位分組
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: unsupported format character ',' (0x2c) at index 1

2.8 通用型別分類

  • 數字(整數、浮點數、小數、分數等):支援加法和乘法等;
  • 序列(字串、列表、元組):支援索引、分片和拼接等;
  • 對映(字典):支援按鍵名稱的索引等;

集合不屬於以上任何一類,它是獨立的分類

  • 不可變類別(數字、字串、元組、不可變集合frozenset)

不可變型別中的物件型別都不支援在原位置修改,但是可以透過執行表示式來建立新的物件然後將返回的結果分配給變數

  • 可變類別(列表、字典、集合、位元組陣列)

可變類別可以不透過生成新的物件直接在原位置上進行修改