1. 程式人生 > 其它 >字串及相關操作

字串及相關操作

一、什麼是字串

  • 在python中字串是基本資料型別,是一個不可變的字元序列

二、字串的駐留機制

  • 僅保留一份相同且不可變字串的方法,不同的值被存放在字串的駐留池中,python的駐留機制對相同的字串只保留一份拷貝,後續建立相同字串時,不會開闢新空間,而是把該字串的地址賦值給新建立的變數
  • 即相同的字串只有一個,只用賦值地址
a='python'
b="python"
c='''python'''

print('a的值:',a,id(a))
print('b的值:',b,id(b))
print('c的值:',c,id(c))

執行結果:

a的值: python 1741697609328
b的值: python 1741697609328
c的值: python 1741697609328

1、駐留機制的幾種情況(互動模式)

  • 字串的長度為0或1時
  • 符號識別符號的字串——字串中只包含大小寫字母、數字、下劃線
  • 字串只在編譯時進行駐留,而非執行時——在編譯時不知道結果
  • 【-5,256】之間的整數數字

2、sys中的intern方法強制2個字串指向同一個物件

3、PyCharm對字串進行了優化處理

4、字串駐留機制的優缺點

  • 當需要值相同的字串時,可以直接從字串池裡拿來使用,避免頻繁的建立和銷燬,提升效率和節約記憶體
  • 在需要進行字串的拼接時建議使用str型別的join方法,而非+,因為join()方法是先計算出所有字元中的長度,然後再拷貝,只new一次物件,效率要比“+”效率高

三、字串的常用操作

1、字串的查詢

  • index():查詢子串substr第一次出現的位置,如果查詢到的子串不存在時,則丟擲異常
  • rindex():查詢子串最後一次出現的位置,如果查詢的子串不存在時,則丟擲異常
  • find():查詢子串substr第一次出現的位置,如果查詢的子串不存在時,則返回-1
  • rfind():查詢子串substr最後一次出現的位置,如果查詢的子串不存在時,則返回-1
demo="hello,hello"

print(demo.index('lo'))
#print(demo.index('savgdh'))#ValueError: substring not found 子串查詢不到,報錯
print(demo.rindex('lo'))
#print(demo.rindex('ahvfgah'))#ValueError: substring not found子串查詢不到,報錯
print(demo.find('lo'))
print(demo.find('sdfbh'))#-1 子串查詢不到,返回-1
print(demo.rfind('lo'))
print(demo.rfind('sdfbh'))#-1 子串查詢不到,返回-1

執行結果:

3
9
3
-1
9
-1

2、字串大小寫轉換操作的方法

  • upper():把字串中所有字元轉化為大寫字母
  • lower():把字串中所有字元轉化為小寫字母
  • swapcase():把字串中所有大寫字母轉為小寫字母,把所有小寫字母轉為大寫字母
  • capitalize():把第一個字元轉換為大寫,把其餘字元轉換為小寫
  • title():把每個單詞的第一個字元轉換為大寫,把每個單詞的剩餘字元變為小寫
#字串中大小寫轉換方法

s='hello,python'
a=s.upper()     #將所有字串轉化為大寫
print(s,type(s))#hello,python <class 'str'>
print(a,type(a))#HELLO,PYTHON <class 'str'>
#使用upper()之後是新建立一個物件
print(id(s))#2610054516336
print(id(a))#2610054846640

b=s.lower()   #將所有字元轉變為小寫
#可以看出,即使是一樣的資料,也會生成一個新的物件
print(s,id(s))#hello,python 2718729137776
print(b,id(b))#hello,python 2718729460272

demo='hello,Python'
demo2=demo.swapcase()#將大寫變為小寫,小寫變為大寫
print(demo,id(demo))  #hello,Python 1827402832368
print(demo2,id(demo2))#HELLO,pYTHON 1827402832752

demo3=demo.capitalize()#第一個字元變為大寫,其餘字元都是小寫
print(demo3,id(demo3)) #Hello,python 1960434162608
print(demo,id(demo))   #hello,Python 1960434162032

demo4=demo.title()     #把每個單詞的第一個字母變為大寫,其餘字元都變成小寫
print(demo4,id(demo4)) #Hello,Python 1440205982960
print(demo,id(demo))   #hello,Python 1440205982128

  

3、字串對齊操作

  1. centeer():居中對齊,第一個引數指定寬度,第二個引數指定填充符,第二個引數是可選的,預設是空格,如果設定寬度小於實際寬度,則返回原字串
  2. ljust():左對齊,第一個引數指定寬度,第二個引數指定填充符,第二個引數是可選的,預設是空格。如果設定寬度小於實際寬度,則返回原字串
  3. rjust():右對齊。第一個引數指定寬度,第二個引數指定填充符,第二個引數是可選的,預設是空格。如果設定寬度小於實際寬度,則返回原字串
  4. zfill():右對齊,左邊用0填充,該方法只接受一個引數,用於指定字串的寬度,如果指定的寬度小於等於字串的長度,則返回字串本身
'''
設定字串對齊
'''

demo='hello,python' #12個字元
#居中對齊
print(demo.center(20))
print(demo.center(20,'*')) #第一個引數指定寬度,第二個指定填充物
print(demo.center(10))     #指定寬度太小,返回原字串
#左對齊
print(demo.ljust(20))
print(demo.ljust(20,'*'))  #第一個引數指定寬度,第二個指定填充物
print(demo.ljust(1))       #指定寬度太小,返回原字串
#右對齊
print(demo.rjust(20))
print(demo.rjust(20,'*'))
print(demo.rjust(10))
#右對齊,左邊用0填充——只接收一個引數,用於指定字串寬度
print(demo.zfill(20))

執行結果:

    hello,python    
****hello,python****
hello,python
hello,python        
hello,python********
hello,python
        hello,python
********hello,python
hello,python
00000000hello,python

Process finished with exit code 0

4、字串的劈分——將字串劃分為列表

split():

  • 從字串的左邊開始劈分,預設的劈分字元是空格字串,返回的值都是一個列表
  • 以通過引數sep指定劈分字串
  • 通過引數maxsplit指定劈分字串時的最大劈分次數,在經過最大次劈分之後,剩餘的子串會單獨做為一部分

rsplit():

  • 從字串的右邊開始劈分,預設的劈分字元是空格字串,返回的值都是一個列表
  • 以通過引數sep指定劈分字串
  • 通過引數maxsplit指定劈分字串時的最大劈分次數,在經過最大次劈分之後,剩餘的子串會單獨作為一部分
lst='hello world 你好'
print(lst)
print(lst.split())
print(lst.split(maxsplit=1))

demo='hello|world|nihao'
print(demo.split('|'))
print(demo.split(sep='|',maxsplit=1))

執行結果:

hello world 你好
['hello', 'world', '你好']
['hello', 'world 你好']
['hello', 'world', 'nihao']
['hello', 'world|nihao']

5、判斷字串操作的方法

  • isidentifier():判斷指定的字串是不是合法的識別符號
  • isspace():判斷指定的字串是否全部由空白字元組成(回車,換行,水平製表符)
  • isalpha():判斷指定的字串是否全部由字母組成
  • isdecimal():判斷指定字串是否全部由十進位制組成
  • isnumeric():判斷指定的字串是否全部數字組成
  • isalnum():判斷指定字串是否全部由字母和數字組成

6、字串替換和合並操作

  • replace():第一個引數指定被替換的子串,第二個引數指定替換子串的字串,該方法返回替換後得到的新的字串,替換前的字串不發生變化,呼叫該方法是可以通過設定第三個引數指定最大替換次數
  • join():將列表或元組中的字串合併成一個字串
'''
字串的替換-生成了新的字串
'''
s='hello,python'
print(s.replace('python','java'))
print(s)

s='hello,python,python,python'
print(s.replace('python','java',2))
print(s.replace('python','java'))

'''
字串的合併-將列表或元組中的字串合併成一個字串
'''
#列表
lst=['hello','java','python']
print(''.join(lst))
print('*'.join(lst))
print('我是分隔符'.join(lst))
#元組
t=('hello','java','python')
print(''.join(t))
#字串
print('*'.join('python'))

運算結果:

hello,java
hello,python
hello,java,java,python
hello,java,java,java
hellojavapython
hello*java*python
hello我是分隔符java我是分隔符python
hellojavapython
p*y*t*h*o*n

7、字串的比較操作

  • 運算子:>,>=,<,<=,==,!=
  • 比較規則:首先比較兩個字串中第一個字元,如果相等則繼續比較下一個字元,依此比較下去,直到兩個字串中的字元不相等時,其比較結果就是兩個字串的比較結果,兩個字串中的所有後續字元將不再被比較
  • 比較原理:兩個字元進行比較時,比較的是其原始值,呼叫內建函式ord可以得到指定字元的原始值。與內建函式ord對應的是內建函式chr,呼叫內建函式chr時指定原始值可以得到其對應的字元(原始值就是ascii)
#字串的比較
print('apple'>'app')
print('apple'>'banana')
#ord函式可以獲得一個字元的原始值
print(ord('a'),ord('b'))#97 98
print(ord('秦'))         #31206
#chr()函式可以從原始值查詢對應的字元
print(chr(97),chr(98))
print(chr(31206))

'''
==與is的區別
==比較的是值
is比較的是id
'''
a=b='python'
c='python'
print(a==b)#True
print(a==c)#True
print(b==c)#True

print(a is b)#True
print(a is c)#True
print(b is c)#True
#字串記憶體的駐留機制
print(id(a))#2922877630640
print(id(b))#2922877630640
print(id(c))#2922877630640

8、字串的切片操作

#字串的切片操作
s='hello,Python'
s1=s[:5]#由於沒有指定初始位置,所以從索引0開始切片
s2=s[6:]#由於沒有指定結束位置,所以切到字串的最後一個元素
s3='!'
newstr=s1+s3+s2

print(s1)#hello
print(s2)#Python
print(s3)
print(newstr)#hello!Python
#可以發現三個id塊都不同,所以對於字串的切片產生了新的物件
print(id(s1))#2964438800624
print(id(s2))#2964438800752
print(id(s3))#2964438467056

'''
切片操作[start:end:step]
'''
print(s[1:5:1])#ello  從1開始截到5(不包含5),步長為1
print(s[::2])#hloPto  預設從0開始,沒有寫結束,預設到字串的最後一個元素,步長為2,兩個元素之間的索引間隔為2
print(s[::-1])#nohtyP,olleh   因為步長是負數,預設從字串的最後一個元素開始,到字串的第一個元素截至
print(s[-6::1])#Python   從索引-6開始,到字串的最後一個元素結束,步長為1

9、格式化字串

三種方式:

  • %作佔位符,%s做字串;%i或%d做整數;%f做浮點數
  • {}作佔位符
  • f-string呼叫
name='張三'
age=30

print('我的名字叫:',name,'今年',age,'歲')
#我的名字叫: 張三 今年 30 歲  可以看見,在name和age的附近多出了空格

#第一種方法:%佔位符
print('我的名字叫%s,今年%d歲' % (name,age))
#第二種方法:{}
print('我叫{0},今年{1}歲,我的名字是{0}'.format(name,age))
#第三種方法:f-string
print(f'我叫{name},今年{age}歲')  

寬度和精度的設定

print('{}'.format(3.1415927))
print('{0:.3}'.format(3.1415927))#.3表示的是一共是三位數

print('{:.3}'.format(3.1415927))
print('{:.3f}'.format(3.1415927))#.3f表示的是有三位小數
#同時設定寬度和精度
print('{0:10.3}'.format(3.1415927))#10表示設定的寬度
print('{0:10.3}'.format(3.1415927))
print('hellohello')

print('%10d' % 99)         #10表示設定的寬度
print('%.3f' % 3.1415926)  #.3f表示是小數點後三位

print('%10.3f' % 3.1415926)#同時設定寬度和精度,一共總寬度為10,小數點後三位

10、字串的編碼轉換

編碼:將字串轉換為二進位制資料(bytes)

解碼:將bytes型別的資料轉換成字串型別

s='天涯共此時'
#編碼
print(s.encode(encoding='GBK'))  #在GBK這種編碼格式中,一箇中文佔兩個位元組
print(s.encode(encoding='UTF-8'))#在UTF-8這種編碼格式中,一箇中文佔三個位元組

#解碼
#byte代表的就是一個二進位制資料(位元組型別的資料)
#編碼和解碼要一一對應
byte=s.encode(encoding='GBK')
print(byte.decode(encoding='GBK'))

byte=s.encode(encoding='UTF-8')
print(byte.decode(encoding='UTf-8'))