一、上节回顾
1,id() 内存地址
2, == 比较的是值
is 比较的是内存地址
数字,字符串,有小数据池,
#内存地址一样的
int -5--256
str:1,不能有空格。
2,长度不能超过20。
3,不能有特殊字符如:#@.....
列表元组字典这些除了赋值的都是内存地址不一样的
py3:
str:表现形式:s = 'alex' 实际编码方式:unicode
bytes:表现形式:s = b'alex' 实际编码方式:utf-8,gbk,gb2312...
s = b'x2ex2ex2ex2ex2ex2e'
unicode:所有字符(无论英文,中文等) 1个字符:4个字节
gbk:一个字符,英文1个字节,中文两个字节。
utf-8:英文 1 个字节,欧洲:2个字节,亚洲:3个字节。
二、数据类型补充
1.元组
tu = (1) tu1 = ('name',) print(tu,type(tu)) # 1 <class 'int'> print(tu1,type(tu1)) tu = ('dfas') tu1 = ('name',) print(tu,type(tu)) # dfas <class 'str'> print(tu1,type(tu1)) tu = (True) tu1 = ('name',) print(tu,type(tu)) # True <class 'bool'> print(tu1,type(tu1)) tu = ([1,2,3]) tu1 = ('name',) print(tu,type(tu)) # [1, 2, 3] <class 'list'> print(tu1,type(tu1)) #当数据类型外边只加括号的时候。这个数据类型还是自己本身,如果想变为元组。那么后边加一个,号
2.,列表当循环列表时,如果在循环中删除某个或者某些元素,列表元素个数改变,索引改变,容易出错。
# #删除奇数位索引值 #方一: a = [1,2,3,4,5,6,7] del a[1::2] print(a) #方法二 a = [1,2,3,4,5,6,7] a = a[0::2] print(a) #方法三(不建议使用此方法,如果有两个相同的元素可能会出错) a = [1,2,3,4,5,6,7] b = a.copy() for i in range(len(b)): if i%2==1: a.remove(b[i]) print(a) #方法四 a = [1,2,3,4,5,6,7] for i in range(0,len(a)): if i%2==1: del a[(i+1)//2] print(a) #方法五 a = [1,2,3,4,5,6,7] b = [] for i in range(len(a)): if i%2 ==0: b.append(a[i]) a = b #方法五 a = [1,2,3,4,5,6,7] b = [] for i in range(len(a)): if i%2 ==0: b.append(a[i]) a = b print(a)''' e = {1:2,3:4} e.pop(1) print(e) # 方法6 a = [1, 2, 3, 4, 5, 6, 7] for i in range(len(a)-1,-1,-1): if i % 2 == 1: del a[i] print(a)
3,字典
当循环字典时,如果在循环中删除某个或者某些键值对,字典的键值对个数改变,长度改变,容易出错。
#删除列表中带K的键值对 l1={'k1':'v1','k2':'v2','k3':'v3','n1':'m1'} #方法一 l1={'k1':'v1','k2':'v2','k3':'v3','n1':'m1'} l2 = {} for i,k in l1.items(): if 'k' not in i: l2[i] = k l1 = l2 print(l1) #方法二 l1={'k1':'v1','k2':'v2','k3':'v3','n1':'m1'} l2 = [] for i in l1: if 'k' in i: l2.append(i) for i in l2: del l1[i] print(l1) #方法三 l1={'k1':'v1','k2':'v2','k3':'v3','n1':'m1'} l2 = list(l1.keys()) for i in l2: if 'k' in i: del l1[i] print(l1) #方法四 l1={'k1':'v1','k2':'v2','k3':'v3','n1':'m1'} l2 = l1.copy() for i in l2: if 'k' in i: del l1[i] print(l1)
4.转化:
1,int --> str :str(int) 2, str ---> int:int(str) 字符串必须全部由数字组成 3,bool ---> str:str(bool) 4,str ----> bool(str) 除了空字符串,剩下的都是True 5,int ---> bool 除了0,剩下的全是True 6,bool ---> int True ---> 1 False ----> 0 7,str ---> list split 8,list ---> str() join 9,元祖列表: tu = (1,2,3) l = list(tu) print(l,type(l)) li = [4,5,6] print(tuple(li),type(tuple(li))) #str ---> list print(list('ab_c')) #str ---> list print(tuple('ab_c')) # 0,"",{},[],(),set() ---->False
a='a' b = 1 d = 1, f = '' g = () h = list(g) e = list(f) # c = list(1,) 报错 c = list(d) print(c) print (d,type(d)) # 一个字母可以通过工厂函数转化 print(e) # 空字符串也可以 print(h) # 空元组也可以
5、列表转化为字典:fromkeys
dic = dict.fromkeys([1,2,3]) # dic1 = dict.fromkeys('abc','杨杰') print(dic) # 如果单独的一个列表,后边没有参数,那么返回的是三个值为None的字典 dic[4] = 'dfdsa' print(dic) # {1: None, 2: None, 3: None, 4: 'dfdsa'} dic = dict.fromkeys(['barry','alex',],[]) dic['ritian'] = [] dic['barry'] = [] dic['barry'].append(11) print(dic) # # {'barry': [11], 'alex': [], 'ritian': []} 如果后边的参数是一个列表(或元组或),那么所有的键值对的值都指向该列表 #即内存地址一样,其中一个列表变化所有值都变化
6、集合
# ①集合的元素是可哈希的,不可变的。②集合本身是不可哈希。列表,字典不能出现,集合也不行③集合是无序的 ④值是唯一的
内建函数创建set代码如下:
se1 = {1,2,3,4,5} print(se1,type(se1)) # {1, 2, 3, 4, 5} <class 'set'> #se2 = {1,'a',2,3,{1,2,3}} 报错 #se2 = {1,'a',2,3,{1,2,3,[1]}} 报错 se2 = {1,'a',2,3,(1,2,3)} print(se2) # 集合是无序的 但是可迭代 可遍历
增:
se1 = {1,2,3,4,5} a = se1.add('老王') #print(a,se1) #集合是可以增的 None {1, 2, 3, 4, 5, '老王'} #update #se1.update('abc') #{1, 2, 3, 4, 5, '老王', 'a', 'b', 'c'}迭代增加 #se1.update((11,22)) # {1, 2, 3, 4, 5, '老王', 11, 22} # se1.update({11,22}) # print(se1) #{1, 2, 3, 4, 5, 11, '老王', 22} 也可以增加集合
删:
se1 = {1,2,3,4,5} # a = se1.remove(1) # print(a,se1) # None {2, 3, 4, 5} 删除指定源元素,没有返回值 没有参数会报错 # a = se1.pop(1) # print(a,se1) #1 {2, 3, 4, 5} 有返回值 随机删除一个元素返回值是该元素 无索引故无参数 # se1.clear() # 清空集合 # print(se1) # set() 这就是空集合 del se1 print(se1) #: name 'se1' is not defined 删除集合
改:
#冻结集合frozenset 它是不可变的,可哈希的。set 是可变的 set中可以包含frozenset # s = frozenset([1,2,33,33,4]) # print(s,type(s)) # se1.add(s) # print(se1) s1 = frozenset(se1) print(s1) # frozenset({1, 2, 3, 4, 5}) 集合也可以转变为冻结集合 s2 = set(s1) print(s2) # {1, 2, 3, 4, 5} 冻结集合可以转变为集合
查:
# 查 由于是可迭代的,故可以用for 循环将其遍历 for i in se1: print(i)
附加功能
t.add('x') # 添加一项 s.update([10,37,42]) # 在s中添加多项 t.remove('H') # 删除一项 len(s) # set 的长度 x in s # 测试 x 是否是 s 的成员 x not in s # 测试 x 是否不是 s 的成员 s.issubset(t) s <= t # 测试是否 s 中的每一个元素都在 t 中 s.issuperset(t) s >= t # 测试是否 t 中的每一个元素都在 s 中 s.union(t) s | t # 返回一个新的 set 包含 s 和 t 中的每一个元素 s.intersection(t) s & t # 返回一个新的 set 包含 s 和 t 中的公共元素 s.difference(t) s - t # 返回一个新的 set 包含 s 中有但是 t 中没有的元素 s.symmetric_difference(t) s ^ t # 返回一个新的 set 包含 s 和 t 中不重复的元素 s.copy() # 返回 set “s”的一个浅复制
# #交集 & intersection # set1 = {1,2,3,4,5} # set2 = {4,5,6,7,8} # print(set1 & set2) # {4, 5} # print(set1.intersection(set2)) # {4, 5} # set1 = {1,2,3,4,5} # set2 = {4,5,6,7,8} # print(set1 | set2) # {1, 2, 3, 4, 5, 6, 7} # print(set2.union(set1)) # {1, 2, 3, 4, 5, 6, 7} # set1 = {1,2,3,4,5} # set2 = {4,5,6,7,8} # print(set1 - set2) # {1, 2, 3} set1独有 # print(set1.difference(set2)) # {1, 2, 3} # print(set2 - set1) # set1 = {1,2,3,4,5} # set2 = {4,5,6,7,8} # print(set1 ^ set2) # {1, 2, 3, 6, 7, 8} # print(set1.symmetric_difference(set2)) # {1, 2, 3, 6, 7, 8} set1 = {1,2,3,4} set2 = {1,2,3,4,5} set3 = frozenset({1,2}) a = (1,) print(set3 < set1) # set3是set1的子集 print(set1.issubset(set2)) # set1<= set2 # set1是set2的子集 print(set2 > set1) # set2 是set1 的超集 print(set2.issuperset(set1)) # set2 >=set1 # 这两个相同,都是说明set2是set1超集。 print(set1.issuperset(a) ) # 符号形式不能和集合外的比较 函数形式的可以和可迭代对象比较
作用:去重
#去重 lst = [1,2,3,4,1] print (list(set(lst))) # [1, 2, 3, 4]
四、赋值和深浅拷贝
将某一数值赋给某个变量的过程,或者将某一变量赋值给另一变量的过程。称为赋值。
l1 = [1,2,3] l2 = l1 l1.append('barry') print(l1) # [1,2,3,'barry'] print(l2) # [1,2,3,'barry'] dic = {'name':'barry'} dic1 = dic dic['age'] = 18 print(dic) # {'name': 'barry', 'age': 18} print(dic1) # {'name': 'barry', 'age': 18} s = 'alex' s1 = s s3 = s.replace('e','E') print(s) # alex print(s1) # alex print(s3) # alEx s1 = s print(id(s),id(s1)) # 相同 s = 'alex ' s1 = 'alex ' print(id(s),id(s1)) # 相同 # 赋值时候,两个变量指向了同一个内存空间,并没有开辟新的空间来 # lst = [1,2,3,4,1] # print (list(set(lst))) # [1, 2, 3, 4] l1 = [288,1,2,3] l2 = l1 l1.append('barry') print(l1[0] is l2[0] ) # True 内层也一样
浅拷贝:创建一个新的对象,其元素是对原对象元素的引用。实现方法:(切片操作、工厂函数、对象的copy方法、模块中的copy函数。)
>>> ssw ='bangzi' >>> ssb =list(ssw) #ssb是通过工厂函数浅拷贝过来的一个新的对象 >>> ssw 'bangzi' >>> ssb ['b', 'a', 'n', 'g', 'z', 'i'] >>> id(ssw),id(ssb) (139798160206232, 139798160220040) #两个对象的内存地址不一样 >>> for x,y in zip(ssw,ssb): #针对于对象中的元素来说,两个对象中的每个元素指向的都是一个元对象。 ... print(id(x),id(y)) ... 139798160566736 139798160335792 139798160718736 139798160372040 139798160206512 139798160567856 通过工厂函数所得到的对象:工厂函数有:list()、tuple()、dict()、str()。 >>> YY1 = [1,2,3,4,5,6] >>> YY2 =tuple(YY1) #序列变元祖 >>> YY2 (1, 2, 3, 4, 5, 6) >>> id(YY1),id(YY2) (139798032994568, 139798159622216) >>> for x,y in zip(YY1,YY2): ... print(id(x),id(y)) ... 9323200 9323200 #对象中的元素与原对象中的元素id号一致。 9323232 9323232 9323264 9323264 9323296 9323296 9323328 9323328 9323360 9323360 通过切片操作得到的对象 >>> a = [1,2,3,4,5] >>> b = a[:3] >>> id(a) >>> id(b) >>> id(b[0]) #对原对象元素的引用。 >>> id(a[0]) >>> id(b[1]) >>> id(a[1]) 通过copy函数得到的对象也是浅拷贝 >>> info = {'name':'kebi','age':'28'} >>> INFO = info.copy() >>> INFO {'name': 'kebi', 'age': '28'} >>> id(info) #内存地址虽然不同 >>> id(INFO) >>> id(info['name']) #元素都指向一个地方,明显的浅拷贝。 >>> id(INFO['name'])
深拷贝:创建一个新的对象,然后递归拷贝原对象所包含的子对象。深拷贝出来的对象和元对象没有关联。
深拷贝和浅拷贝的区别仅仅是对组合对象来所。所谓的组合对象就是包含了其它对象的对象,例如列表、元祖等数据容器。
对于非容器类型(例如:字符串、数字和其他原子类型)来说,没有拷贝一说,产生的对象都是对原对象的应用。
区别在于新对象中的元素与原对象中的元素是否存在联系。如果有联系则属于浅拷贝,否则属于深拷贝。
import copy l1 = [258,[258,33,44],3,4,] l2 = copy.deepcopy(l1) l1[0] = 111 print(l1,l2) l1[1].append('barry') print(l1,l2) # [111, [22, 33, 44], 3, 4] [1, [22, 33, 44], 3, 4] [111, [22, 33, 44, 'barry'], 3, 4] [1, [22, 33, 44], 3, 4] print(l1[1][0] is l2[1][0]) # True 内层的非容器元素地址相同,内层的容器元素地址不同