5內置數據結構_bytes_bytearray_切片_封裝解構

bytesbytearray

 

python3引入兩個新類型:

bytes不可變,字節序列,可理解爲字節組成的列表;

bytearray,字節數組,可變,所有數據都可轉爲字節數組來處理;

 

字符串與bytes

字符串是字符組成的有序序列,字符可用編碼來理解;

bytes是字節組成的有序的不可變序列;

bytearray是字節組成的有序的可變序列;

 

編碼與解碼:

字符串按照不同的字符集編碼encode,返回字節序列bytes

encode(encoding='utf-8',errors='strict')-->bytes

字節序列按照不同的字符集解碼decode,返回字符串;

bytes.decode(encoding='utf-8',errors='strict')-->str

bytearray.decode(encoding='utf-8',errors='stric')-->str

 

bytes定義:

bytes(),空bytes,沒用;

bytes(int),指定字節的bytes,被0填充,intsize(最低位爲1,奇數,用於判斷奇偶數);

bytes(iterable_of_ints)-->bytes[0-255]int組成的可迭代對象,常用;

bytes(string,encoding[,errors])-->bytes,等價於string.encode()

bytes(bytes_or_buffer)-->bytesimmutable copy of bytes_or_buffer,從一個字節序列或者buffer複製出一個新的不可變的bytes對象;

使用b前綴定義,只允許基本ASCII使用字符形式,>b'abc9',十六進制表示>b'\x41\x61'

b'...',是一種格式,用於表示字節序列,引號內的內容不能作爲字符串;

 

例:

In [2]: bytes(range(100))

Out[2]: b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abc'

In [3]: bytes(range(1000))   #超過255

---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-3-a7e270a52df2> in <module>()

----> 1 bytes(range(1000))

ValueError: bytes must be in range(0, 256)

In [4]: bytes([1,3,5])   #1,3,5ASCII前面的部分

Out[4]: b'\x01\x03\x05'

In [5]: bytes([91,93,95])

Out[5]: b'[]_'

In [7]: bytes('abc','utf8')   #bytes(string,encoding[,errors]),編碼寫爲utf8utf-8都可

Out[7]: b'abc'

In [8]: bytes('abc','utf-8')

Out[8]: b'abc'

In [9]: s1='abc'.encode()   #常用

In [10]: type(s1)

Out[10]: bytes

In [11]: s1.decode()

Out[11]: 'abc'

In [12]: s2=bytes(s1)

In [13]: s1 == s2   #==比較內容

Out[13]: True

In [14]: id(s1) is id(s2)   #is比較內存地址

Out[14]: False

In [15]: type(s2)

Out[15]: bytes

 

bytes操作:

str類似,都是不可變類型,所以方法很多都一樣,只不過bytes的方法,輸入是bytes,輸出是bytes

bytes.fromhex(string),類方法,python中對象的方法(類方法)相當於c/c++中的靜態方法,python中的靜態方法是另一種概念,string必須是2個字符的十六進制形式,'6162 6a6b'空格將被忽略;

hex(),返回十六進制表示的字符串;

索引,b'abcdef'[2]-->int,返回該字節對應的數,int類型;

 

例:

In [16]: b'abcdef'.replace(b'f',b'k')

Out[16]: b'abcdek'

In [17]: b'abc'.find(b'b')

Out[17]: 1

In [18]: b'abc'.split(b'b')

Out[18]: [b'a', b'c']

In [19]: bytes.fromhex('6162 096a 6b00')

Out[19]: b'ab\tjk\x00'

In [20]: b'abc'.hex()

Out[20]: '616263'

In [21]: 'abc'.encode().hex()

Out[21]: '616263'

In [22]: b'abcdef'[2]

Out[22]: 99

 

bytearray定義:

bytearray(),空bytearray

bytearray(int),指定bytebytes,被0填充;

bytearray(iterable_of_ints)-->bytearray[0-255]int組成的可迭代對象;

bytearray(string,encoding[,errors])-->bytearray,近似string.encode(),不過返回bytearray可變對象;

bytearray(bytes_or_buffer),從一個字節序列或者buffer複製出一個新的可變的bytearray對象;

注意:b前綴定義的類型是bytes類型,沒有前綴指定bytearray類型;

 

bytearray操作:

bytes類型的方法相同,另多出一些可變類型的方法;

bytearray.fromhex(string)string必須是2個字符的十六進制的形式,'6162 6a6b'空格將被忽略;

hex(),返回十六進制表示的字符串;

append(int)

insert(index,int)

extend(iterable_of_ints),將一個可迭代的整數集合追加到當前bytearray

pop(index=-1),從指定索引上移除元素,默認從尾部移除;

remove(value),找到第一個value移除,找不到拋異常ValueError

注意:append(),insert(),extend(),pop(),remove(),這些方法使用int類型,值在[0,255]

clear(),清空bytearray

reverse(),翻轉bytearray,就地修改;

 

例:

In [23]: bytearray(b'abcdef').replace(b'f',b'k')

Out[23]: bytearray(b'abcdek')

In [24]: bytearray(b'abc').find(b'b')

Out[24]: 1

In [25]: bytearray.fromhex('6162 09 6a 6b00')

Out[25]: bytearray(b'ab\tjk\x00')

In [26]: bytearray('abc'.encode()).hex()

Out[26]: '616263'

In [27]: b1=bytearray()

In [28]: b1.append(97)

In [29]: b1

Out[29]: bytearray(b'a')

In [30]: b1.append(98)

In [31]: b1

Out[31]: bytearray(b'ab')

In [33]: b1.insert(1,98)

In [34]: b1

Out[34]: bytearray(b'abb')

In [35]: b1.extend([65,66,67])

In [36]: b1

Out[36]: bytearray(b'abbABC')

In [37]: b1.remove(66)

In [38]: b1

Out[38]: bytearray(b'abbAC')

In [39]: b1.pop()

Out[39]: 67

In [40]: b1.reverse()

In [41]: b1

Out[41]: bytearray(b'Abba')

In [42]: b1.clear()

 

 

 

線性結構(排隊、順序結構、sequence序列):可迭代for...inlen(),可獲取長度,在外計數,O(1)__雙下劃線開頭的方法;通過下標可以訪問;可切片;

學過的線性結構:list,tuple,str,bytes,bytearray;

 

切片:

通過索引區間訪問線性結構的一段數據;

sequence[start:stop],表示返回[start,stop]區間的子序列,不包括索引爲stop的字符;

支持負索引;

start0可以忽略,start一定要在stop的左邊;

stop爲末尾,可省;

超過上界(右邊界),就取到末尾;超過下界(左邊界),取到開頭;注意有方向,理解爲一維的x-------->,方向自左向右;

[:],表示從頭取到尾,全部元素被取出,等效於copy()方法;

[start:stop:step],步長切片,step爲步長,可以正負整數,默認是1step要和start:stop同向,否則返回空序列;

 

例:

In [1]: s='www.magedu.com'

In [2]: s[4:10]

Out[2]: 'magedu'

In [3]: s[:10]

Out[3]: 'www.magedu'

In [4]: s[4:]

Out[4]: 'magedu.com'

In [5]: s[:]

Out[5]: 'www.magedu.com'

In [6]: s[:-1]   #不包括最後一個字符

Out[6]: 'www.magedu.co'

In [7]: b1=b'www.magedu.com'

In [8]: b1[-40:40]

Out[8]: b'www.magedu.com'

In [9]: bytearray(b1)[-40:40]

Out[9]: bytearray(b'www.magedu.com')

In [10]: bytearray(b1)[-40:4]

Out[10]: bytearray(b'www.')

In [11]: bytearray(b1)[-10:-4]

Out[11]: bytearray(b'magedu')

In [12]: bytearray(b1)[-10:-12]

Out[12]: bytearray(b'')

In [13]: s

Out[13]: 'www.magedu.com'

In [14]: s[4:10:2]

Out[14]: 'mgd'

In [15]: s[4:10:-2]

Out[15]: ''

In [16]: s[-10:-4:-2]

Out[16]: ''

In [17]: s[-4:-10:2]

Out[17]: ''

In [18]: s[-4:-10:-2]   #逆序找並反向打印

Out[18]: '.dg'

 

 

 

封裝&解構:

java中的裝箱拆箱是兩碼事;

python特有語法,被很多語言學習和借鑑;

 

封裝:

將多個值使用逗號分割,組合在一起;

本質上,返回一個元組,只是省略了小括號;

 

解構:

把線性結構的元素解開,並順序的賦給其它變量;

左邊接納的變量數要和右邊解開的元素個數一致;

解構是python提供的很好的功能,可方便提取複雜數據結構的值,配合_丟棄變量使用,會更加便利;

 

python3的解構:

使用*變量名接收,但不能單獨使用,也不能使用>=2次,否則分不出到底分給哪個變量多些;

*變量名收集後組成一個列表;

 

例:

In [1]: t1=(1,2)   #定義爲tuple

In [2]: t2=1,2   #12封裝成tuple常用,語法糖,封裝優先用tuple,解構優先用list

In [3]: type(t1)

Out[3]: tuple

In [4]: type(t2)

Out[4]: tuple

 

例:

In [6]: a=4

In [7]: b=5

In [8]: temp=a

In [9]: a=b

In [10]: b=temp   #這三句相當於temp=b,a;a,b=temp相當於a,b=b,a

In [11]: a

Out[11]: 5

In [12]: b

Out[12]: 4

 

例:

In [13]: a=4

In [14]: b=5

In [15]: temp=b,a

In [16]: a,b=temp

In [17]: a

Out[17]: 5

In [18]: b

Out[18]: 4

 

例:

In [17]: a

Out[17]: 5

In [18]: b

Out[18]: 4

In [19]: a,b=b,a   #常用,右邊封裝(先封裝成tuple),左邊解構(重新賦值)

In [20]: a

Out[20]: 4

In [21]: b

Out[21]: 5

 

例:

In [22]: lst=[3,5]

In [23]: first,second=lst

In [24]: print(first,second)

3 5

In [25]: a,b=1,2   #先封裝再解構

In [26]: a,b=(1,2)   #直接解構

In [27]: a,b=[1,2]

In [28]: a

Out[28]: 1

In [29]: b

Out[29]: 2

In [30]: a,b={10,20}   #非線性結構

In [31]: a

Out[31]: 10

In [32]: b

Out[32]: 20

In [33]: a,b={'a':10,'b':20}   #非線性結構,將字典的key傳給ab

In [34]: a

Out[34]: 'b'

In [35]: b

Out[35]: 'a'

 

In [36]: a,*b=1,2,3,4,5   #blist

In [37]: a

Out[37]: 1

In [38]: b

Out[38]: [2, 3, 4, 5]

In [39]: [a,b]=(1,2)   #左邊雖是list結構,但沒賦給變量,只將list結構中的a,b變量賦值了

In [40]: a

Out[40]: 1

In [41]: b

Out[41]: 2

In [42]: [a,b]=1,2

In [43]: (a,b)=30,40

In [44]: a

Out[44]: 30

In [45]: b

Out[45]: 40

In [46]: lst=list(range(1,101,2))

In [47]: head,*mid,tail=lst

In [48]: *lst2=lst   #python3解構時*變量名不能單獨使用,直接寫爲lst2=lst即可

  File "<ipython-input-48-90c12e6f75df>", line 1

    *lst2=lst

             ^

SyntaxError: starred assignment target must be in a list or tuple

In [51]: head,*mid1,*mid2,tail=lst   #分不出到底*mid1多還是*mid2

  File "<ipython-input-51-7380bcea7c56>", line 1

    head,*mid1,*mid2,tail=lst

                             ^

SyntaxError: two starred expressions in assignment

 

 

 

_丟棄變量:

如果不關心一個變量,就可定義改變變量名字爲_

這是一個慣例,是一個不成文的規定,不是標準;

_是一個合法的標識符,也可以作爲一個有效的變量使用,但定義爲_就是希望不要被使用,除非你明確的知道這個數據需要使用;

_,這個變量本身無任何意義,沒有任何可讀性,所以不是用來給人使用的,python中很多庫都使用這個變量,使用非常廣泛,請不要在不明確變量作用域的情況下,使用_,導致和庫中的_衝突;

 

例:

In [52]: head,*mid,tail='abcdefghijklmn'

In [53]: type(mid)

Out[53]: list

In [54]: lst=[9,8,7,6,5]

In [55]: head,*_,tail=lst

In [56]: print(_)

[8, 7, 6]

In [57]: _,*_,tail=lst   #_爲同一個變量,覆蓋了,賦值即定義

In [58]: print(_)

[8, 7, 6]

 

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章