4-Python數據類型之元組-字符串

1 元組概念

        元組(類型爲 tuple)和列表十分類似,可是元組和字符串同樣是不可變的。git

1.1 元祖的特色

  • 元組能夠存儲一系列的值,使用小括號來定義,是一個有序的元素的集合。
  • 元組內的元素是不可變
  • 當元組內嵌套列表這種引用類型時,元組的不可變表示的是執行這個列表的內存地址不會變,當直接操做元組嵌套的列表時,是能夠進行修改的

1.2 元組的定義

格式api

tuple() -> 工廠函數,用於建立並返回一個空元組
tuple(iterable) -> 使用可迭代對象的元素,來初始化一個元組

例子數組

In [18]: t=(1)    # 會認爲()只是優先級
In [19]: type(t) 
Out[19]: int
In [20]: t=(1,)
In [21]: type(t)
Out[21]: tuple     # tuple表示元組類型
 
#引用其餘元組
In [22]: a=(1,2,3)
In [23]: t=('123',a)
In [24]: t
Out[24]: ('123', (1, 2, 3))
 
#經過索引只引用某一個值
In [27]: t=('123',a[1])
In [28]: t
Out[28]: ('123', 2)


# tuple接受一個可迭代對象轉換爲元組
In [35]: tuple(range(1,7,2))                                                                                    
Out[35]: (1, 3, 5)

1.3 元組的訪問

        元組和列表在內存中的格式是相同的,都是線性順序結構,因此咱們能夠像列表同樣,使用索引訪問元組的元素,其中元組支持正索引負索引,一樣不支持索引超界,會提示IndexErroride

In [49]: b = (1,2,3)                                                                                                
In [50]: b[1]                                                                                                       
Out[50]: 2
In [51]: b[-1]                                                                                                        
Out[51]: 3

        須要注意的是在對元組進行修改的時候,元組自己是沒法進行修改的,但當元組內嵌套的是列表這種引用類型時,元組的不可修改指的是元組中存儲的嵌套列表的內存地址不可修改,但你能夠對這快內存地址裏的數據進行修改,由於這是列表的特性。函數

In [44]: a                                                                                                           
Out[44]: (1, 2, [1, 2], 1, 2, [1, 2], 1, 2, [1, 2])
In [45]: a[2][0] = 100         # 能夠對嵌套的列表進行賦值操做                                                                                       
In [46]: a                                                                                                           
Out[46]: (1, 2, [100, 2], 1, 2, [100, 2], 1, 2, [100, 2])
In [47]: a[3] = 100      # 修改指向是不被容許的                                                                                             
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-47-2b62bbdeb061> in <module>
----> 1 a[3] = 100

TypeError: 'tuple' object does not support item assignment

1.4 元組的查詢

        咱們經過使用元組的index方法和count來獲取和統計元組中的元素。優化

T.index(value, [start, [stop]]) --> integer -- 返回元組內匹配value的第一個元素的index,

T.count(value) --> integer -- 統計value在元組中出現的次數,不存在時,則返回0

注意:t.index和t.count由於要遍歷列表全部,時間複雜度都是O(n),隨着列表的元素增長,而效率降低this

In [4]: a=('1','2','3')
In [7]: a.count("4")     # 不存在,返回0
Out[7]: 0
In [8]: a.count("1")
Out[8]: 1
 

# a.index(value) 用來返回value在元組中的索引,若是value不在元組中,則會報錯。若是有多個,默認返回第一個(能夠指定從哪一個索引開始查找到某個索引結束,指定範圍區間)
In [4]: a=('1','2','3')
In [9]: a.index('1')
Out[9]: 0
In [10]: a.index('3')
Out[10]: 2
In [57]: a = ('1','2','3')                                                                                            
In [58]: a.index('4')     # 不存在,就會報錯                                                                                             
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-58-dca64b8e9162> in <module>
----> 1 a.index('4')

ValueError: tuple.index(x): x not in tuple
>>> t1
('a', 'b', 'a', 'b', 'a', 'b', 'a', 'b')
>>> t1.index('a',5,7)    # 在指定的區間內查找
6

2 命名元組

        命名元組是元組的子類,因此它也是沒法進行修改的,它的特色是能夠針元組的對字段進行命名。
格式spa

namedtuple(typename, field_names, *, verbose=False, rename=False, module=None) --> 返回一個擁有命名字段的 新的元組的子類

經常使用參數含義3d

  • typename: 通常和命名元組的名稱相同。
  • field_names: 能夠是空白字符或逗號分隔的字段的字符串,能夠是字段的列表

    namedtuple 存放在 collections 包中,因此須要先進行導入

>>> from collections import namedtuple    
>>> Point = namedtuple('Point', ['x', 'y'])  # 建立一個名爲Point的命名元組類,其中含有兩個字段
>>> p = Point(11, 22)             # 建立一個實例,11會傳遞給x,22會傳遞給y。
>>> p[0] + p[1]                     # 能夠經過索引訪問
33
>>> p.x + p.y                       # 也能夠經過字段名訪問
33
>>> p.x = 33            # 沒有辦法進行修改的                                                                                         
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-63-dac7085722b7> in <module>
----> 1 p.x = 33

AttributeError: can't set attribute

3 字符串

        字符串是Python中比較重要的數據類型,是以單引號'或雙引號"括起來的任意文本,好比'abc',"xyz"等等。請注意,''或""自己只是一種表示方式,不是字符串的一部分,所以,字符串'abc'只有a,b,c這3個字符。若是'自己也是一個字符,那就能夠用""括起來,好比"I'm OK"包含的字符是I,',m,空格,O,K這6個字符。有三種方法定義字符串:單引號雙引號三引號,須要注意的是字符串是不可變對象,而且從Python3起,字符串就是Unicode類型。
定義方式

str1='this is string'
str2="this is string"
str3='''this is string'''   # 也能夠是三個雙引號,三個引號能夠多行註釋可是不能單雙混合,三重引號除了能定義字符串之外,還能夠表示註釋。
str4='hello\n world' # 在print打印字符串的時候\n會被看成換行符進行打印
str5=r'hello\n world' # 前面使用了r對字符串進行總體轉義,所見即所得
str6='hellow\\nworld' # 固然使用\也能夠對特殊符號進行脫義
str7=R'hello\nworld' # 和r相同

3.1 字符串的基本操做

        Python的字符串是一個有序序列,因此他能夠和列表同樣使用下標來訪問元素,可是因爲它是不可變類型,因此沒法對字符串中的某個字符進行修改,下面介紹下字符串的基本操做。

Python中沒有字符的概念,嚴格來說,說字符是不許確的,字符串是由一個個字符串(字符)組成的,雖然聽起來很彆扭,但真的就是這樣 - -!。

3.1.1 字符串的訪問

        字符串和列表是類似,都是順序的線性結構,因此它能夠被索引,也能夠被遍歷。字符串的索引相似數組的下標:

In [3]: a='1234567'
In [4]: a[0] --> # 下標從0開始,0表示第一個數
Out[4]: '1'
In [5]: a[3] --> # 表示第四個數
Out[5]: '4'
In [3]: a[1] = 100   # 字符串沒有辦法被修改                                                                                                  
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-8554a2b011c3> in <module>
----> 1 a[1] = 100

TypeError: 'str' object does not support item assignment

In [4]:
In [6]: for i in a:       # 能夠被for循環進行迭代
   ...:     print(i) 
   ...:                                                                                                             
1
2
3
4
5
6
7
In [7]: list(a)        # 能夠被看成一個可迭代對象傳給list,轉換爲一個列表                                                                                               
Out[7]: ['1', '2', '3', '4', '5', '6', '7']

3.1.2 字符串的拼接

        當咱們須要把多個字符串鏈接在一塊兒,那麼就須要對字符串進行拼接,python提供了join方法,+號,以及*號,使咱們方便的完成需求。

S.join(iterable) -> str  --> 使用s對可迭代對象進行拼接,返回拼接後的字符串。
  • join: S能夠爲任意字符,包括空。可迭代對象中的元素必須是字符串類型
  • +: 把兩個字符串直接進行鏈接,返回一個新的字符串
  • *: 把字符串重複複製N次,返回一個新的字符串
In [11]: str1                                                                                                         
Out[11]: ['h', 'e', 'l', 'l', 'o']
In [12]: ''.join(str1)                                                                                                
Out[12]: 'hello'
In [13]: str2 = ''.join(str1)                                                                                          
In [14]: str2                                                                                                         
Out[14]: 'hello'
In [17]: '-'.join(str1)      # 使用-進行拼接                                                                                           
Out[17]: 'h-e-l-l-o'
In [15]: str2 * 2                                                                                                     
Out[15]: 'hellohello'
In [16]: str2 + str2                                                                                                  
Out[16]: 'hellohello'

In [18]: lst = ['1',['1','2'],'3']                                                                                    
In [19]: ''.join(lst)                   # lst的第1個元素是列表,不是字符串,沒辦法進行拼接,會報錯                                                                              
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-19-58ac5d2512ec> in <module>
----> 1 ''.join(lst)

TypeError: sequence item 1: expected str instance, list found

In [20]

3.2 字符串分割

        字符串中有關於字符分割功能的主要有兩類,split類和partition類,他們分別適用於不用的場景。但用的比較多的是split

  • split類:將字符串按照分割符分隔成若干字符串,並返回列表
  • partition類:將字符串按照分割符分割成2段,返回這2段和分隔符組成的三元組
S.split(sep=None, maxsplit=-1) -> list of strings -->  從左至右對字符串s進行切割,分割符爲sep,默認爲儘量多的空字符,maxsplit表示分割幾回,默認爲-1,所有進行分割,返回一個切割後的列表。

S.partition(sep) -> (head, sep, tail)  --> 從左至右對字符串s進行切割,必須指定一個切割符sep,返回一個三元組,其中中間的元素爲分割符,第一個和最後一個元素爲按照分隔符分開後的先後兩個元素。當分隔符沒法對字符串進行分割時,返回的是 字符串,空,空,組成的三元組。

例子

In [20]: s = "hello world I am Daxin"                                                                                 
In [21]: s.split()       # 默認使用空格進行分割                                                                                              
Out[21]: ['hello', 'world', 'I', 'am', 'Daxin']
In [23]: s.split('o')         # 使用字母o進行分割                                                                                        
Out[23]: ['hell', ' w', 'rld I am Daxin']   
In [24]: s.split('o',1)                   # 使用字母o進行分割,而且只分割1次                                                                          
Out[24]: ['hell', ' world I am Daxin']
In [25]: s.split(sep='o',maxsplit=1)         # 也能夠指定關鍵字進行傳參                                                                         
Out[25]: ['hell', ' world I am Daxin']
In [26]: s.partition(' ')                  # 使用' '進行分割,返回三元組                                                                           
Out[26]: ('hello', ' ', 'world I am Daxin')
In [27]: s.partition('o')                                                                                             
Out[27]: ('hell', 'o', ' world I am Daxin')


# 當分割符不存在時
In [29]: s = "helloworldIamDaxin"                                                                                     
In [30]: s.split()     # 必定會返回一個列表,若是沒有被切分,那麼會發那會一個元素的列表                                                                                                   
Out[30]: ['helloworldIamDaxin']
In [31]: s.partition(' ')         # 必定會返回一個三元組,若是沒有被切分,那麼會從字符串的最右邊切開,造成一個三元組,和 一個空字符組成的列表                               
Out[31]: ('helloworldIamDaxin', '', '')
In [32]: s.partition('12')                                                                                           
Out[32]: ('helloworldIamDaxin', '', '')

固然split類還包含了其餘兩個方法:

S.rsplit(sep=None, maxsplit=-1) -> list of strings --> 功能與split相同,只不過從右開始

S.splitlines([keepends]) -> list of strings  --> 按照行來切分,keepends表示是否保留換行符,True表示保留,False表示不保留,默認爲False

In [33]: s = 'I am Super Man'                                                                                         
In [34]: s.rsplit('u')      # 不指定分割次數,通常和split是同樣的效果                                                                                             
Out[34]: ['I am S', 'per Man']
In [35]: s.rsplit('a')                                                                                                
Out[35]: ['I ', 'm Super M', 'n']
In [37]: s.rsplit(sep='a',maxsplit=1)     #  當指分割1次時,會從右邊開始切開                                                                             
Out[37]: ['I am Super M', 'n']
In [40]: s = 'hello\nworld\rI\nam\r\ndaxin'                                                                           
In [41]: s.splitlines()                                                                                               
Out[41]: ['hello', 'world', 'I', 'am', 'daxin']
In [42]: s.splitlines(True)             # 默認不保留分隔符,True表示保留分隔符                                                                             
Out[42]: ['hello\n', 'world\r', 'I\n', 'am\r\n', 'daxin']

partition類和split類似,還有個rpartition函數,也是從右開始截取,須要注意的是,當分隔符沒法對字符切分時,返回的是字符串,組成的三元組。

3.3 字符串大小寫

  • upper:將字符串轉換爲大寫字母
  • lower:將字符串轉換爲
  • swapcase: 大小寫對調
  • capitalize:轉換成首字母大寫的單詞格式
  • title: 轉換成每一個單詞首字母大寫的標題模式
In [51]: s = 'hElLo wORld i aM dAxin'                                                                                 
In [52]: s.upper()                                                                                                    
Out[52]: 'HELLO WORLD I AM DAXIN'
In [53]: s.lower()                                                                                                    
Out[53]: 'hello world i am daxin'
In [54]: s.swapcase()                                                                                                 
Out[54]: 'HeLlO WorLD I Am DaXIN'
In [55]: s.capitalize()                                                                                               
Out[55]: 'Hello world i am daxin'
In [56]: s.title()                                                                                                    
Out[56]: 'Hello World I Am Daxin'

3.4 字符串排版

  • center(width [,fillchar]): 居中顯示,參數width表示總體寬度,fillchar表示填充字符,默認填充字符爲空
  • zfill(width):居右顯示,參數width表示總體寬度,使用0進行填充
  • ljust(width [, fillchar]):左對齊,width表示總體寬度,fillchar表示填充字符
  • rjust(width [, fillchar]):右對齊,width表示總體寬度,fillchar表示填充字符
In [61]: a                                                                                                            
Out[61]: 'abc'
In [62]: a.ljust(20,'-')                                                                                              
Out[62]: 'abc-----------------'
In [63]: a.rjust(20,'-')                                                                                              
Out[63]: '-----------------abc'
In [64]: a.center(10,'-')                                                                                             
Out[64]: '---abc----'

3.5 字符串修改

        what?你前面說字符串是不可變的吧,爲何這裏又說字符串的修改?你在逗我嗎。呵呵噠。

S.replace(old, new[, count]) -> str  --> 對字符串S進行查找,將指定的old字符串轉換爲new字符串,count表示替換的次數,默認表示重複替換全部

S.strip([chars]) -> str --> 將字符串s進行處理,從字符串的兩邊刪除掉匹配chars的字符串,chars能夠是多個單字符,默認是全部空白字符(\n,\r\n,\r,\t等等都包含)

注意:replace的替換是生成一個新的字符串,而不是修改原字符串,這也是字符串修改的原理

In [3]: s                                                                                                             
Out[3]: ' \n\t Hello World \n\r'
In [4]: s.strip()     # '不指定chars,默認是任意多個空白字符                                                                                                
Out[4]: 'Hello World'
In [5]: s.strip(' \n\tHd')       # 若是指定了chars,那麼就挨個使用char進行匹配去除                                                                                     
Out[5]: 'ello World \n\r'
In [6]: s.strip(' \n\rHd')                                                                                            
Out[6]: '\t Hello Worl'
In [7]: s.replace('World','Daxin')                                                                                    
Out[7]: ' \n\t Hello Daxin \n\r' 
In [8]: s.replace('o','O')         # 默認從頭至尾進行替換                                                                                     
Out[8]: ' \n\t HellO WOrld \n\r'
In [9]: s.replace('o','O',1)         # 指定替換1次                                                             
Out[9]: ' \n\t HellO World \n\r'

3.6 字符串查找

        咱們有不少的時候要判斷關鍵字是否存在一個字符串中,那麼咱們就須要在字符串中遍歷查找,是否有匹配的字符串。python提供了find,rfind,index,count等函數用於完成需求。

S.find(sub[, start[, end]]) -> int  --> 從左開始在字符串S中查找sub字符串,其中起始位start,結束位end,默認爲整個字符串,返回找到的字符串的開頭索引位,若是沒有找到,那麼會返回-1

S.rfind(sub[, start[, end]]) -> int  --> 從右開始在字符串S中查找sub字符串,其中起始位start,結束位end,默認爲整個字符串,返回找到的字符串的開頭索引位,若是沒有找到,那麼會返回-1

S.index(sub[, start[, end]]) -> int  --> 從左開始在字符串S中查找sub字符串,其中起始位start,結束位end,默認爲整個字符串,返回找到的字符串的開頭索引位,若是沒有找到,那麼會報異常

S.count(sub[, start[, end]]) -> int  --> 從左開始在字符串S中統計sub字符串出現的次數,其實起始位置爲Start,結束位爲end,默認爲整個字符串。沒有找到返回0

index和count方法因爲是遍歷查找,因此時間複雜度都是O(n),會隨着字符串序列的數據規模的增大,而效率降低,若是沒要在字符串中進行查找,仍是建議使用find函數。

In [15]: s = 'abc abc abc'                                                                                            
In [16]: s.find('a')                                                                                                  
Out[16]: 0
In [17]: s.find('a',1,-1)      # 指定區間, 注意這裏-1表示最後1位,可是不包含-1,相似於[1,-1)                                                                                      
Out[17]: 4
In [18]: s.find('a',-1,-15)                                                                                           
Out[18]: -1
In [19]: s.rfind('a')                                                                                                 
Out[19]: 8
In [20]: s.rfind('a',2,-1)                                                                                            
Out[20]: 8
In [21]: s.rfind('c',2,-1)                                                                                            
Out[21]: 6
In [22]: s.rfind('c',2,-100)    # end點超出範圍,會沒法找到,start,end表示起始和終止,最好不要使用負數表示區間                                                                                     
Out[22]: -1
In [23]: s.index('a')                                                                                                 
Out[23]: 0
In [24]: s.index('a',2)     # 從索引爲2,開始向右查找                                                                                          
Out[24]: 4
In [25]: s.index('e')       # 沒找到,直接報異常                                                                                     
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-25-90b1c28da6f0> in <module>
----> 1 s.index('e')

ValueError: substring not found
In [26]:

3.7 字符串判斷

        Python的字符串對象提供了兩個函數,用於對字符串的起始位和結尾位來進行匹配,它們是startswithendswith

S.startswith(prefix[, start[, end]]) -> bool  --> 判斷字符串prefix是不是字符串S的起始字符串,start表示起始位置,end表示末尾,默認爲0,即整個字符串S,返回bool類型。

S.endswith(suffix[, start[, end]]) -> bool  --> 判斷字符串prefix是不是字符串S的結束字符串,start表示起始位置,end表示末尾,默認爲0,即整個字符串S,返回bool類型。
In [32]: s                                                                                                            
Out[32]: 'abc abc abc'
In [33]: s.startswith('bc',1,-1)    # 從s的[1,-1)開始判斷'bc'是不是開頭                                                                                     
Out[33]: True
In [34]: s.endswith('bc',2,-1)      # 從s的[2,-1)開始匹配'bc'是不是結尾                                                                                 
Out[34]: False                     # 這裏-1不包含,因此返回False
In [35]: s.endswith('bc',3,7)                                                                                         
Out[35]: True
In [36]: s.startswith('abc')                                                                                          
Out[36]: True
In [37]: s.endswith('bc')                                                                                             
Out[37]: True

        除了判斷開始和結尾,Python的字符串還提供了部分函數,用來判斷字符串內的元素類型,好比判斷字符串是不是純數字組成?是不是純字母組成等,這些函數的返回值統一都爲bool型,能夠做爲if語句的條件表達式

str.isalpha() # 是不是字母嗎
str.isalnum() # 是數字和字母的組合嗎
str.isdigit() # 是否全是十進制數字,int
str.isdecimal() # 判斷是不是數字類型,包含float,但不包含負數
str.islower() # 判斷字符串是否全是小寫字母
str.isupper() # 判斷字符串是否全是大寫字母
str.isspace() # 是不是空白字符
str.isnumberic() # 判斷是不是正整數
str.isidentifier() # 是不是一個合規的變量標識符

3.8 字符串格式化

        字符串格式化是咱們須要重點掌握的東西,在早期的Python中使用的是C語言風格的字符串替換,使用起來比較難看,不符合python的風格(固然是個人猜想,哈哈)。後來Python推薦使用內置的format函數來對字符串進行格式化。
        字符串格式化是一種拼接字符串輸出樣式的手段,更靈活方便,以前咱們使用join和+來對字符串進行拼接。

  • join:只能使用分隔符,且要求被拼接的是可迭代對象且元素必須是來字符串類型
  • +: 使用起來比較方便,可是非字符串須要先轉換爲字符串才能夠進行拼接。

3.8.1 C語言格式化

        在Python 2.5版本之前,只能使用printf style風格的print輸出,這種風格來自於C語言的printf函數,它有以下格式要求。(不建議使用,瞭解便可,Pythoner仍是理解format就好。)

  1. 佔位符:使用%和格式字符串組成,例如%s,%d等。使用s時,內部其實會調用str()函數進行轉換
  2. 佔位符中還能夠插入修飾字符,例如%03d表示打印3個位置,不夠的話,前面補0
  3. format % value 格式字符串和被格式字符串之間使用%分割
  4. values只能是一個對象,或是一個與格式字符串佔位符數量相等的元組,或一個字典
In [38]: 'I am %03d' % 20        # 表示3爲數字,不夠的話高位補0                                                                                     
Out[38]: 'I am 020'
In [39]: 'I like %s' % 'Python'      # 字符串格式化
In [50]: 'I am %s' % 20      # 20會被str做用後,傳遞給字符串                                                                                
Out[50]: 'I am 20'
Out[39]: 'I like Python'
In [41]: '%3.2f%%,0x%x,0X%02X' % (89.7654,10,15)     # 3.2f表示最長3爲,小數點後精度爲2位,當數字大時總體長度會被撐開,x表示16進制,02X表示兩位顯示,高位補0                                                                 
Out[41]: '89.77%,0xa,0X0F'
In [45]: "I am %-5d" % 20                                                                                             
Out[45]: 'I am 20   '
In [46]: "I am %5d" % 20                                                                                              
Out[46]: 'I am    20'

3.8.2 format格式化

        Python中推崇使用format函數來對字符串進行格式化。

'{}{XXX}'.format(*args, **kwargs)  -> str  --> 函數的通常格式,{}表示佔位符,使用format中的參數進行傳遞

format很是靈活,下面是基本使用方法說明:

  1. args是可變的位置參數,是一個元組
  2. kwargs是可變關鍵字參會蘇,是一個字典
  3. 花括號表示佔位符
  4. {}表示按照順序匹配位置參數{n}表示取位置參數中索引爲n的值
  5. {xxx} 表示在關鍵字參數中搜索名稱一致的值,kwargs必須放在位置參數的後面
  6. {{}}表示打印花括號
In [52]: '{}:{}'.format('10.0.0.13','8888')       # 按照位置格式化,第一個元素給第一個括號,第二個元素給第二個括號                                                                    
Out[52]: '10.0.0.13:8888'            # 
In [53]: '{host}:{}:{}'.format('10.0.0.13','8888',host='daxin')   # 命名格式化,host表示只獲取關鍵字爲host的值來填充,其餘沒有指定關鍵字的佔位符,則按照位置參數進行傳遞,並格式化顯示                                                    
Out[53]: 'daxin:10.0.0.13:8888'
In [54]: '{hostname} {}:{}'.format('10.0.0.13','8888',hostname='daxin')                                               
Out[54]: 'daxin 10.0.0.13:8888'        # 訪問元素的方式進行字符串格式化(很是不經常使用)
In [55]: '{0[0]}:{0[1]}'.format(['10.0.0.13','8888'])                                                                 
Out[55]: '10.0.0.13:8888'

In [57]: from collections import namedtuple                                                                           
In [58]: Point = namedtuple('_Point',['x','y'])                                                                       
In [59]: p = Point(4,5)                                                                                               
In [60]: "{{{0.x},{0.y}}}".format(p)   # 兩個花括號重疊表示打印一個花括號,因爲p對象含有x和y屬性,因此能夠在字符串格式化時直接引用                                                                            
Out[60]: '{4,5}'

3.8.3 對齊

固然字符串還提供了多種的對齊方式,便於咱們對輸出內容作一個簡單的優化。

  • <:左對齊(默認)
  • >:右對齊
  • ^: 居中顯示

    對齊方式須要在佔位符內使用:號進行分割

In [61]: '{:5}'.format('2')     #   打印以訛字符串,這個字符串佔5位,默認靠左對齊                                                                                                                
Out[61]: '2    '
In [62]: '{:>5}'.format('2')     # > 表示向右對齊                                                                                                                  
Out[62]: '    2'
In [65]: '{:0<5}'.format('2')     # 字符串站5位,向左對齊,其餘爲使用0填充(能夠簡寫爲'{:<05}')                                                                                                          
Out[65]: '20000'
In [66]: '{:>05}'.format('2')                                                                                                                       
Out[66]: '00002'
In [71]: '{:*>5}'.format('2')     # > 表示向右對齊,其餘位用*填充                                                                                                           
Out[71]: '****2'

In [67]: '{:0^5}'.format('2')     # 居中顯示,使用0進行填充                                                                                                                 
Out[67]: '00200'
In [69]: '{:*^5}'.format('2')                                                                                                                       
Out[69]: '**2**'

當填充符爲數字的時候,能夠與寬度寫在一塊兒,好比 {:0<5} --> {:<05} , {:0^5} --> {:^05}

3.8.9 小數點與進制

雖然用的很少,仍是這裏仍是舉例說明一下進制和小數的使用方法

In [74]: "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)                                                                                
Out[74]: 'int: 42; hex: 2a; oct: 52; bin: 101010'
In [75]: "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)                                                                             
Out[75]: 'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010'
In [76]: octets = [10,0,0,13]                                                                                                                      
In [78]: '{:02X}{:02X}{:02X}{:02X}'.format(*octets)                                                                                                 
Out[78]: '0A00000D'
In [79]: '{:02X}-{:02X}-{:02X}-{:02X}'.format(*octets)                                                                                              
Out[79]: '0A-00-00-0D'
  • d: 表示十進制
  • x: 表示十六進制
  • o: 表示八進制
  • b: 表示二進制
  • F: 表示浮點型
  • #: 表示添加進制前綴
  • *[1,2,3]: 表示把列表中的元素結構出來:*[1,2,3] --> 1,2,3
In [82]: "{}".format(3**0.4)    # 默認按照字符串打印                                                                                                                        
Out[82]: '1.5518455739153598'
In [83]: "{:f}".format(3**0.4)         # f表示填充位爲小數,小數是有精度的                                                                                                              
Out[83]: '1.551846'
In [84]: "{:02f}".format(3**0.4)         # 表示小數的長度爲2,可是若是小數的位數超過2,會直接撐開                                                                                                           
Out[84]: '1.551846'
In [85]: "{:10f}".format(3**0.4)       #  表示小數的長度爲10,默認是右對齊                                                                                                            
Out[85]: '  1.551846'
In [86]: "{:<10f}".format(3**0.4)          # 左對齊                                                                                                         
Out[86]: '1.551846  '
In [89]: "{:.2f}".format(3**0.4)          # .2f表示 小數點後取兩位的浮點型                                                                                                          
Out[89]: '1.55'
In [90]: "{:3.2f}".format(3**0.4)          # 總長3爲,小數點後保留2位,若長度超出,則撐開                                                                                                         
Out[90]: '1.55'
In [91]: "{:2.2f}".format(3**0.4)                                                                                                                   
Out[91]: '1.55'
In [92]: "{:2.2%}".format(3**0.4)          # 使用百分比顯示                                                                                                         
Out[92]: '155.18%'

4 切片

        說到切片那麼不得不提線性結構,爲何?由於線性結構均可以進行切片操做,除了切片,線性結構其餘的特色還有

  • 可迭代(for val i ...)
  • len()能夠獲取長度
  • 能夠經過下標進行訪問(有序)
  • 列表、元組、字符串、bytes、bytearray都屬於線性結構,因此均可以被切片。
            那什麼是切片?咱們說經過索引區間訪問線性結構一段數據的方法就叫作切片,須要注意的是切片操做會引發內存複製,當對一個過於龐大的線性結構進行切片的時候,請慎重考慮內存使用率的問題。切片的表達方式和基本特色有:
  1. 格式:sequence[start:stop:[,step=1]] 返回[start, stop, step=1)的前閉後開子序列。
  2. 支持負索引。注意方向問題
  3. 當start爲0或stop爲0時,能夠省略。[:]表示複製原線性結構數據(注意當對象爲list時,屬於淺copy)
  4. 超過上屆(右),則取到末尾;超過下屆(左),則取到開頭。
  5. start必定要在stop的左邊
In [72]: a = 'hello world , My name is daxin'                                                                                                       
In [73]: a[2:-1]                                                                                                                                  
Out[73]: 'llo world , My name is daxi'
In [74]: a[2:]                                                                                                                                      
Out[74]: 'llo world , My name is daxin'
In [75]: a[-100:]                                                                                                                                   
Out[75]: 'hello world , My name is daxin'
In [76]: a[10:-100]     # stop位置在start左邊,因此沒辦法取出,若是實在想要倒着取,那麼須要使用步長                                                                                                                             
Out[76]: '' 
In [77]: a[10:-100:-1]      # 負步長就能夠造成開閉區間,注意是從起始位開始按照step取的(因此會倒序排列返回)                                                                                                                        
Out[77]: 'dlrow olleh'

注意:

  • 切片並不會對原數據進行修改,會返回新的數據
  • 若是不是用變量接受,那麼就會被標記爲待回收
  • 因爲是新生成的數據,因此內存地址和原數據內存地址必定不相同

4.1 切片賦值

        既然能夠進行切片,那麼就會引伸出來,是否能夠進行切片賦值,什麼是切片賦值?它該如何表示?下面以列表例進行說明。

  • 切片操做寫在等號的左邊
  • 被插入的可迭代對象在等號右邊
In [79]: lst = list(range(10))                                                                                                                      
In [80]: lst                                                                                                                                        
Out[80]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [81]: lst[1:3]                                                                                                                                  
Out[81]: [1, 2]

In [82]: lst[1:3] = 1                                                                                                                               
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-82-7fef59136c7e> in <module>
----> 1 lst[1:3] = 1

TypeError: can only assign an iterable

In [83]: lst[1:3] = [100,200]                                                                                                                       
In [84]: lst                                                                                                                                        
Out[84]: [0, 100, 200, 3, 4, 5, 6, 7, 8, 9]

仔細看上面示例代碼會發現幾個問題:

  1. lst[1:3] = 1 表示切片賦值
  2. 切片賦值,賦的值必須是一個可迭代對象
  3. 切片賦值改變了原數據
  4. 字符串、元組這類不可變的元素,沒法使用切片賦值(理由請看3)

    當咱們使用切片時,它會產生新的內存地址來存放生成的新列表,可是若是把切片操做放在賦值操做的左邊時,那麼就至關於引用了原列表的[start:stop]的索引,這種操做是不會生成新的內存空間的,換句話來說就是直接對原列表進行了insert操做.

In [86]: lst                                                                                                                                        
Out[86]: [0, 100, 200, 3, 4, 5, 6, 7, 8, 9]
In [87]: lst[1:3] = []               # 這種操做至關於list.remove                                                                                                               
In [88]: lst                                                                                                                                        
Out[88]: [0, 3, 4, 5, 6, 7, 8, 9]
In [89]: lst[1:3] = [100,200]        # 這種操做至關於在1:3的位置上進行了list.insert                                                                                                              
In [90]: lst                                                                                                                                        
Out[90]: [0, 100, 200, 5, 6, 7, 8, 9]

咱們知道list在進行insert和remove時的時間複雜度都是O(1),在進行切片賦值時也容易讓人難以理解,因此建議不要使用這種方法。

相關文章
相關標籤/搜索