python線性數據結構 --tuple和str

本文使用到的函數
項目 函數
元組 index() ; count() ; len()
字符串查詢 find()/rfind() ; index() ; count() ; len()
字符串分割 split()/rsplit(); splitlines() ;partition()/rpartition()
字符串查詢 replace()
字符串移除 strip() ; rstrip()/lstrip()
字符串首尾判斷 endswith() ; startswith()
其他函數 見本文具體科目

元組tuple

1.一個有序元素組成的集合
2.使用小括號來封裝元素
3.元素不可改變,字面常量元素不可修改
4.引用類型元素中的子元素可以修改,但是引用類型本身地址沒有發生變化,因此引用類型元素的子元素可以適當修改

初始化

tuple() -> empty tuple
tuple(iterable) -> tuple initialized from iterable’s items

t1=()
t2=(1,)  #二元組,這個逗號必須添加,不然t2就變成了一個整型數據
t3=(1,2,3) #三元組
t4=(1,)*5 #生成五元組
t5=1,'a' #初始化時使用逗號
t6=(1,2,3,1,2,3,) ##元素可以重複
t7=tuple() #生成空元祖
t8=tuple(range(10)) #生成元組
t9=tuple([1,2,3]) #使用列表生成元組

索引

元組索引的使用和列表的使用規則是一樣的:不可以超界
具體使用方式可以查看列表的索引:列表索引

>>> s1=('a','1',2,33,[2,3],(1,'a'))
>>> s1[1],s1[5][1]  
('1', 'a')

元組的查詢

方法和列表一樣,時間複雜度也是一樣的。index,count,len等函數
index函數
返回某個value的索引值,會遍歷元組,時間複雜度爲O(n)

index函數的語法模式:
s1.index(value, start_index, stop_index)
>>> s1=('a','1',2,33,[2,3],(1,'a'))
>>> s1.index((1,'a'),2)        ##默認的index範圍爲[0,len(tuple))前閉後開區間
5
>>> s1.index((1,'a'),2,5)      #這樣會報錯,報元組中沒有此元素,因爲2,5的區間是不包含5的
>>> s1.index((1,'a'),2,100)    #這個是可以執行的,但是直接通過索引來訪問的話,如果索引超界就會報錯,如下
>>> s1[100]  
IndexError: tuple index out of range

count函數
返回某個value在元組中出現的次數:會遍歷元組,時間複雜度爲O(n)

count函數語法模式:
s1.count(value)
>>> s1=('a','1',2,33,[2,3],(1,'a'),'a')
>>> s1.count('a')      ##此value不會返回元素中引用類型中的元素
2

len函數
直接返回元組的的長度,因爲元組的長度就記錄在元組的元數據中,因此len函數的時間複雜度爲O(1)

len函數的語法模式:
len(object),len函數直接調用對象即可執行
>>> s1=('a','1',2,33,[2,3],(1,'a'),'a')
>>> len(s1)
7

tuple元素操作

元組元素的個數已經在初始化時就決定好了,因此不能增加元組的元素個數也不能刪除元組中的元素
注意:元組在定義時逗號很重要

>>> t1 = ([1]) * 3   ##由於t1在定義時元素後面沒有添加逗號,因此t1其實是一個列表
>>> t1[1] = 100 # ?
>>> print(type(t1))
<class 'list'>

修改引用類型元素中的子元素不會改變引用類型地址,但是如果使用乘法來生成元組,其中的引用類型就會批量改變

>>> t1=([1],)*3
>>> t1[1][0]=100   ##修改第二個元素中的第一個子元素,由於這是引用類型,因此可以修改成功,但是由於元組是使用乘法生成的,
>>> print(t1)	   ##因此每個引用類型元素的地址都是一樣的,一旦一個改變,其他的都會跟着改變
([100], [100], [100])

直接修改引用類型元素,這會導致引用類型元素的改變,因此,在元組中這是不可能成功的

>>> t1=([1],)*3
>>> t1[1]=100  ##這就相當於將引用類型元素改編成整型元素100,這是修改元素,因此在元組中會報錯
TypeError: 'tuple' object does not support item assignment

字符串str

1.由一個個字符組成的有序的序列
2.使用單引號,雙引號或三引號包圍
3.字符串是字面常量,不可改變
4.想得到需要的字符串可以使用新增字符串的方式
5.python3之後字符串的類型都是Unicode類型

>>> print(type('aaa'))
<class 'str'>    ##字符串類型

初始化
字符串的初始化直接使用賦值語句即可完成,字符串內容使用單引號,雙引號,三引號來包圍。還可以使用R,r,f前綴來完成特殊功能

s1='string'        #使用單引號包圍
s2="string2"       #使用雙引號包圍
s3='''this is a "string",'啦啦啦''''  ##使用三引號包圍
s4='hello \n world'  ##換行符會換行
s5=r'hello \n world' ##r前綴會導致後續字符串中的轉義字符失效,\n不會換行,只會打印'\n'這兩個字符
s6='c:\windows\nt'   ##也會被換行
s7=R"c:\windows\nt"  ##不會換行,R前綴有着r前綴類似的功能
s8='c:\windows\\nt'  ##不會換行,因爲第二個\已經被轉義,打印出來的結果爲c:\windows\nt
name='tom'
age=22
s9=f'{name}:{age}'  ##可以使用f前綴來格式化輸出
s10="""select * from student where name='tom'""" 

索引

字符串是有序序列,可以使用索引來訪問,索引的範圍也是從0開始,但是不能通過索引來修改

>>> s10="""select * from student where name='tom'""" 
>>> s10[3] ##字符e
>>> s10[4]=a  ##這樣會報錯,因爲字符串是字面常量,不可修改
TypeError: 'str' object does not support item assignment

連接

+加號:

將兩個字符串連接起來組成一個新的字符

>>> str1='name'
>>> str2='tom'
>>> print(str1+':'+str2)  ##可以添加多個字符和字符串,使用加號‘+’連接

join函數:
sep.join(iterable)

使用指定字符串作爲分隔符,將可迭代對象中的各個字符使用分隔符連接起來
可迭代對象必須是個字符串
將會生成一個新的字符串

>>> L1=['a','b','c']
>>> str=''.join(L1)  ##將分隔符設置爲空,這樣就能無縫連接 列表中的各個元素
>>> print(str)
abc

>>> import random
>>> random.sample('abcdefghijklmnopqrstuvwxyz',2)
['q', 'e']  ##生成的是一個列表
>>> str2=''.join(random.sample('abcdefghijklmnopqrstuvwxyz',2)) ##使用join函數來組合random生成的元素
>>> print(str2)
wq

print('-'.join(range(5)))

這種格式是不行的,因爲range生成的是整形數據,而join需要的是字符串,因此會報錯

>>> print('-'.join(range(5))) 
TypeError: sequence item 0: expected str instance, int found

字符串查詢

find函數、index函數和count函數
find函數

  • find(sub,start[,end]) --> int
    在指定的區間內[start,end),查找子串sub,這個區間是左閉右開區間
>>> s = 'heiedu.edu'
>>> print(s.find('edu'))
>>> print(s.find('edu', 3))
>>> print(s.find('edu', 4))
>>> print(s.find('edu', 6, 9))
>>> print(s.find('edu', 7, 20))
>>> print(s.find('edu', 200))
3
3
7
-1
7
-1
  • rfind(sub,start[,end]) --> int
    在指定的區間內[start,end),查找子串sub,這個區間也是左閉右開區間
    不管是find還是rfind函數,索引的範圍都是正索引,並且順序都是從左至右依次增大,只是查找時方向相反而已
>>> s = 'magedu.edu'
>>> print(s.rfind('edu'))
>>> print(s.rfind('edu', 3))
>>> print(s.rfind('edu', 4))  ##索引的範圍從4開始向右增加,查找時從右至左開始查找,找到第一個即返回正索引
>>> print(s.rfind('edu', 6, 9)) ##依然不包括索引9,所以找不到字符串
>>> print(s.rfind('edu', 7, 20)) 
>>> print(s.rfind('edu', 200)) #從索引200開始查找,肯定找不到,返回-1
>>> print(s.rfind('edu', -100))  ##索引範圍可以超限,只要在所包含的範圍內找到字符串即可返回其正索引
7
7
7
-1
7
-1
7

index函數

index(sub,start(,end)) --> int
rindex(sub,start(,end)) --> int

index函數的用法和find函數類似,只不過在找不到符合條件的值時會返回ValueError錯誤

count函數
在指定的區間內統計字符串出現的次數

count(sub,start(,end)) -->int

時間複雜度

1.find函數,index函數和count函數的時間複雜度都爲O(n)
2.find會遍歷字符串,直到找到符合條件的字符串爲止
3.index函數跟find函數一樣
4.count必定會遍歷字符串

len函數

1.直接返回字符串的長度
2.時間複雜度爲O(1)
3.len值保存在字符串的元數據中

字符串分割

字符串分割常用的函數主要包括這幾種:split函數,rsplit函數,splitlines函數,partition函數,rpartition函數

split函數和splitlines函數

split(sep=None[,maxsplit=n]) --> list of str 按照sep符來切割字符串,maxsplit表示最大的切割次數,默認爲全部切割,設置-1也表示全部切割
rsplit(sep=None[,maxsplit=n]) --> list of str從右邊開始切割,不過返回的列表仍然是從左至右顯示
splitlines(keepends) --> list of str按照行來切割字符串,keepends表示是否保留行分隔符      
split函數和splitlines函數的區別:

split函數在分割時會返回分割符兩端的字符,如果分割後某端沒有字符,則會返回一個空字符,用單引號包圍
split函數在分割空字符串時,會返回一個包含空字符的非空列表
split函數默認分隔符爲空格
splitlines函數分割則不同,在分割空字符串時,會返回一個空列表
splitlines函數在處理字符串末尾的換行符時,不會導致一個新行產生,但split函數則會產生新的分割段

>>> "".split('\n'), "Two lines\n".split('\n')
([''], ['Two lines', ''])       #返回包含空字符的非空列表,末尾分隔符會導致新行的產生
>>> "".splitlines(), "One line\n".splitlines()
([], ['One line'])              #返回空列表,末尾分隔符不會導致新行產生
>>> x='a-b-c-d-e-f-g'
>>> x.split('-',maxsplit=-1)
['a', 'b', 'c', 'd', 'e', 'f', 'g']

>>> x='a b c d'
>>> x.split()
['a', 'b', 'c', 'd']

>>> x='a-b-c-d-e-f-g'
>>> x.rsplit('-')      #不設置maxsplit時默認爲全部分割
['a', 'b', 'c', 'd', 'e', 'f', 'g'] #從右邊開始切割時,顯示的順序仍然是從左至右

>>> x='a\n_aaa\neeee\n\rma'  ##行分隔符有\n,\r,\r\n
>>> x.splitlines() #splitlines默認按換行符切割
['a', '_aaa', 'eeee', '', 'ma']  ##連續兩個分隔符時,中間會有一個空字符

>>> x='\na\n_aaa\neeee\n\rma\naa\n'
>>> x.splitlines(keepends=1)  ##設置keepends爲1可以顯示行分隔符
['\n', 'a\n', '_aaa\n', 'eeee\n', '\r', 'ma\n', 'aa\n']

>>> x='\na\n_aaa\neeee\n\rma\naa\n'
>>> x.splitlines()
['', 'a', '_aaa', 'eeee', '', 'ma', 'aa'] ##與上個例子對比可以發現,行分隔符在字符串頭部時會出現一個空字符
										  ##或者連續兩個行分隔符也會多一個空字符

partition函數與rpartition函數

partition(sep) --> (head,sep,tail) 從左至右,遇到分隔符就將字符串分割成兩部分,返回一個三元組(前一部分,分隔符,後一部分)
rpartition(sep) -->(head,sep,tail) 與partition相反。

注意事項:
- 分隔符sep必須指定
- partition如果沒有匹配到分隔符,那麼就返回(整個字符串,空字符,空字符)
- rpartition如果沒有匹配到分隔符,那麼就返回(空字符,空字符,整個字符串)
- 分隔符都放在三元組的中間

>>> x='a b c d'
>>> x.partition(' ')
('a', ' ', 'b c d')

>>> x='a-b-c-d'
>>> x.partition(',')
('a-b-c-d', '', '')

>>> x='a-b-c-d'
>>> x.rpartition(',')
('', '', 'a-b-c-d')

字符串替換

replace()

replace(old,new[,count]) --> str
字符中找到匹配項就替換,然後返回一個新的字符串
count表示替換的次數,默認爲全部替換
>>> a='www.baidu.com'
>>> a.replace('www','web')
web.baidu.com

>>> a='www.baidu.com'
>>> a.replace('w','a',2)  ##只替換兩次
aaw.baidu.com

字符串移除

strip函數,lstrip函數,rstrip函數

strip([chars]) --> str #移除字符串兩端的包含在chars字符集中的字符
lstrip([chars]) -->str #移除字符串左側的相應字符
rstrip([chars]) -->str #移除字符串右側的相應字符
x=' ' + 'www.aaa.www' #先在字符串左側加上一個空字符
print(x.strip())   #默認去除字符串兩端的空字符
print(x.strip('w')) #去除字符串兩端的w字符
print(x.rstrip('w')) #去除字符串右側的w字符
print(x.lstrip('w')) #去除字符串左側的w字符
www.aaa.www  #去除了左側的空字符
 www.aaa.    #左側有空字符,所以只去除了右側的w字符
 www.aaa.    #只去除右側的w字符
 www.aaa.www #左側有空字符,因此字符串不做修改

字符串首尾判斷

startswith函數和endswith函數

startswith(suffix[,start[,ends]]) --> bool#在指定區間內字符串是否以suffix開始
endswith(suffix[,start[,ends]]) --> bool#在指定區間內字符串是否以suffix結束
x='www.baidu.com'
print(x.startswith('ww')) #符合條件
print(x.startswith('w',2)) #符合條件
print(x.startswith('com',9))#索引9開始的字符串是".com",不符合條件
print(x.endswith('com')) #符合條件

其他函數

upper()大寫,字符串轉換
lower()小寫
swapcase() 交換大小寫
isalnum() -> bool 是否是字母和數字組成
isalpha() 是否是字母
isdecimal() 是否只包含十進制數字
isdigit() 是否全部數字(0~9)
isidentifier() 是不是字母和下劃線開頭,其他都是字母、數字、下劃線,判斷是不是標識符
islower() 是否都是小寫
isupper() 是否全部大寫
isspace() 是否只包含空白字符
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章