Python基本数据解构

  文章主要内容是List,Tuple,Bytes,Bytearray的数据结构相关,包括判断数据类型,数据结构的一些基本增删改查,update,remove,insert,clear等,以及 “浅复制” 和 “深复制” 等知识

Python数据解构

数据结构分类

数值型:
    int、float、conmplex、bool
序列对象:
    字符串 str
    列表 list
    tuple
键值对:
    集合 set
    字典 dict

类型判断

type(obj),返回类型,而不是字符串
isinstance(obj,calss_or_tuple),返回布尔值

举例:
>>> a=123
>>> type(a)
<class 'int'>
>>>

>>> type(b)
<class 'str'>
>>>

>>> isinstance(a,str)
False
>>> isinstance(a,int)
True
>>>

>>> type(1+True)
<class 'int'>

列表list

list特性
列表内的个体称为元素,由若干个元素组成列表
元素是可以任意对象,int,str,obj,list
列表内元素有顺序,可以使用索引
线性的数据结构
用[]表示

列表是可变的

>>> lst=list()
>>> lst
>>> lst=[2,5,7,'ab']
>>> lst=lst(range(5))
>>> lst
[0, 1, 2, 3, 4]
>>>

列表索引访问

索引也叫下标
正索引:从左至右,从0开始
负索引:从右至左,从-1开始
正负索引不能超出界限,否则会报错:IndexError
列表通过所应访问:list[index],index就是索引,使用中括号访问

索引查询:
>>> a=[1,2,3,4,5] #从0开始
>>> a[1]
2
>>> a[:-1]
[1, 2, 3, 4]
>>> a[0:2]
[1, 2]
>>> a[1:4]
[2, 3, 4]
>>> a[-3:-1]
[3, 4]
>>>

列表元素“增删改查“操作

通过索引修改元素:
>>> a=[1,2,3,4,5]
>>> a[1]='a'
>>> a
[1, 'a', 3, 4, 5]
>>>

append增加,(实在list尾部增加蒜素)
>>> a.append(6)
>>> a
[1, 'a', 3, 4, 5, 6]
>>>

insert插入,(指定索引位置插入元素)
>>> a.insert(0,9) #在索引为 “0” 的位置插入 “9”
>>> a
[9, 1, 'a', 3, 4, 5, 6]
>>>

extend拓展,(在列表末尾一次性追加另一个序列中的多个值,用新列表扩展原来的列表)
>>> b=('a','b','c')
>>> a.extend(b)
>>> a
[9, 1, 'a', 3, 4, 5, 6, 'a', 'b', 'c']
>>>

remove删除,(在列表从左到右查找第一个匹配的值,移除该元素)
>>> a=[1,3,1,4]
>>> a.remove(1)
>>> a
[3, 1, 4]
>>>

pop删除,(不指定索引,就弹出列表最后一个值)
>>> a=[1,2,3,4,5,6,7]
>>> a.pop()
7
>>> a
[1, 2, 3, 4, 5, 6]
>>> a.pop(0)  #指定弹出索引为 0 的元素
1
>>> a
[2, 3, 4, 5, 6]
>>>

clear,清空列表所有元素,剩下一个空列表
>>> a=[1,2, 3, 4, 5]
>>> a.clear()
>>> a
[]
>>>

列表其他操作

reverse反转操作
>>> a=[1,2,3,4,5]
>>> a.reverse()    >>> a
[5, 4, 3, 2, 1]
>>>

sort排序
>>> a=[9,6,3,7,2,8]
>>> a.sort()
>>> a
[2, 3, 6, 7, 8, 9]
>>>

列表复制

In [1]: lst0 = list(range(4))
In [2]: lst0
Out[2]: [0, 1, 2, 3]

In [3]: lst2 = list(range(4))
In [4]: print(lst0 == lst2)
True
In [5]: lst1 = lst0

In [6]: lst1[2] = 10

In [7]: print(lst0)
[0, 1, 10, 3]

copy复制,为浅复制
>>> lst0=[1,[2,3,4],5]
>>> lst2 = lst0.copy()
>>> lst2
[1, [2, 3, 4], 5]

浅复制后元素的地址空间是一致的
>>> lst2 = lst0.copy()
>>> id(lst0[1][2])
140710918730832
>>> id(lst2[1][2])
140710918730832

>>> lst2[1][2]=9  #可以看到修改lst2的值,lst0也会被修改
>>> lst2
[1, [2, 3, 9], 5]
>>> lst0           
[1, [2, 3, 9], 5]
>>>

浅复制修改完2个列表元素的空间地址一起被修改
>>> lst2[1][2]=9
>>> id(lst2[1][2])
140710918730544
>>> id(lst0[1][2])
140710918730544
>>>


deepcopy,深copy
>>> import copy
>>> lst0=[1,[2,3,4],5]
>>> lst2=copy.deepcopy(lst0)
>>> lst2[1][2]=6  #深copy不会修改lst0的值

>>> id(lst2[1][2]) #可以看到深copy和之前浅copy的地址是不一致的
140710918730672

>>> lst2
[1, [2, 3, 6], 5]
>>> lst0
[1, [2, 3, 9], 5]  


浅复制和深复制的区别:
浅复制遇到引用类型,就是只复制了父类型,不会对子类也复制,用的是同一块地址
深复制就是重新开辟了一个新的地址空间, 是完全独立的

白话解释:
浅复制:分手后藕断丝连
深复制:离婚

元组tuple:

一个有序的元素组成的集合,使用小括号()表示
元组是 “不可变” 对象
元组的定义及初始化
>>> t=tuple(range(5))
>>> t
(0, 1, 2, 3, 4)

>>> t=(1)
>>> type(t)  #没加逗号,类型为int
<class 'int'>
>>> t=(1,) #元组要加逗号
>>> type(t)
<class 'tuple'>
>>>

元组的元素访问:

索引查询:
-支持索引(下标)
-正索引:从左到右,从0开始
-负索引:从右到左,从-1开始
正负索引不可超界,否则会报错:IndexError

>>> t=(1,2,4,5,6)
>>> t[1]   #访问第一个元素
2
>>> t[1:4] #访问第一到第四之间的元素 
(2, 4, 5)
>>> t[1:]  #访问下标1后面的所有元素
(2, 4, 5, 6)
>>> t[:-2]  #访问下标-2之前的元素
(1, 2, 4)
>>> t[2:-1] #访问第二个到下标为-1之间的元素
(4, 5)


count:返回匹配的次数
>>> t=(1,2,1,3,1,1)
>>> t.count(1) #匹配 “1” 的次数
4
>>>

len:返回元素的个数
>>> t
(1, 2, 1, 3, 1, 1)
>>> len(t)  #元组 "t" 一共有6个元素
6
>>>

元组只能读,增、改、删的方法都没有

命名元组namedtuple:

namedtuple是继承自tuple的子类,namedtuple创建一个和tuple类似的对象,而且对象可以拥有可访问的属性

>>> from collections import namedtuple
#定义了一个namedtuple类型point,并包含了x,y2个属性
>>> point=namedtuple('point',['x','y'])
>>> p=point(23,45)
>>> p.x
23
>>> p.y
45
>>>

bytes和bytearray

bytes:不可变字节序列
bytearray:字节数组,可变序列

bytes操作
>>> b'abcd'.replace(b'a',b'b')
b'bbcd'
>>> b'abcd'.find(b'b')
1
>>>

bytes.hex():返回16进制表示字符串
>>> 'abc'.encode().hex()
'616263'
>>>

bytearray基本定义:(返回一个新字节数组),元素可变
>>> bytearray()
bytearray(b'')
>>> bytearray(b'')
bytearray(b'')
>>> bytearray([1,2,3])
bytearray(b'\x01\x02\x03')
>>> bytearray('abcd','utf8')
bytearray(b'abcd')
>>>

bytearray.append(int):在尾部追加一个元素
bytearray(b'abc') 
>>> b.append(12)
>>> b
bytearray(b'abc\x0c')
>>>

bytearray.insert(int):在指定索引插入一个元素
>>> b.insert(1,90) #在索引为1的位置插入一个值
>>> b
bytearray(b'5Zabc\x0c')
>>>

bytearray.remove(value):移除对应的值
>>> b.remove(90)
>>> b
bytearray(b'5abc\x0c')
>>>

bytearray.pop(index):从指定索引移除元素,默认从尾部开始
>>> b.pop()
12
>>> b
bytearray(b'5abc')
>>>

bytearray.reverse():翻转bytearray
>>> b
bytearray(b'5abc')
>>> b.reverse()
>>> b
bytearray(b'cba5')
>>>

bytearray.clear():清空bytearry
>>> b
bytearray(b'cba5')
>>> b.clear()
>>> b
bytearray(b'')
>>>

编码与解码

编码:字符串按照不同的字符集编码encode返回字节序列bytes
bytes.encode(encoding='utf-8',errors="strict") --> bytes

解码:字节序列按照不同字符集解码decode返回字符串    
bytes.decode(encoding='utf-8',errors="strict") --> str
bytearray.decode(encoding='utf-8',errors="strict") --> str


来个例子:
>>> "中国".encode('utf-8')
b'\xe4\xb8\xad\xe5\x9b\xbd'  #将中文解码成bytes
>>>
>>> b'\xe4\xb8\xad\xe5\x9b\xbd'.decode()  #将bytes解码成中文
'中国'
>>>