pathon 基础学习-集合(set),单双队列,深浅copy,内置函数

一、collections系列:

collections其实是python的标准库,也就是python的一个内置模块,因此使用之前导入一下collections模块即可,collections在python原有的数据类型str(字符串), int(数值), list(列表) tuple(元组), dict(字典)的基础之上增加一些其他的数据类型即方法,具体如下:

1、Counter(dict):计数器,扩展的字典的方法,对指定数据的字串做统计出现的次数,结果是一个元组,如:

1 import  collections2 li = ("asdasdsdasdahjlklknlknfd")3 a = collections.Counter(li)4 print(a)56 执行结果:7 Counter({'d': 5, 's': 4, 'a': 4, 'k': 3, 'l': 3, 'n': 2, 'j': 1, 'h': 1, 'f': 1})

2、most_common():不加参数以列表里面加元组方式显示每个字符串出现多少次,加数字表示最少出现括号里面传递的数字次数,如:

1 import  collections2 li = ("asdasdsdasdahjlklknlknfd")3 a = collections.Counter(li)4 print(a.most_common(2)) #显示出现次数最多的前2个5 print(a.most_common(5)) #显示出现次数最多的前5个67 执行结果:8 [('d', 5), ('s', 4)]9 [('d', 5), ('s', 4), ('a', 4), ('k', 3), ('l', 3)]

3、collections.items:以字典结果方式显示每个元素出现的次数生成一个迭代器,可以使用for循环遍历每个元素:,如下:

 1 import  collections 2 li = ("asdasdsdasdahjlklknlknfd") 3 a = collections.Counter(li) 4 for k,v in a.items():  #相当是对collections.Counter的结果又做了二次操作 5     print(k,v) 6 7 执行结果: 8 j 1 9 f 110 l 311 d 512 h 113 n 214 k 315 a 416 s 4

4、collections.elements:获取每个到每个元素并生成一个迭代器,可以使用for循环遍历每个元素:

1 import  collections2 li = ("asdasdsdasdahjlklknlknfd")3 a = collections.Counter(li)4 for k in a.elements():5     print(k)

5、collections.update:对同一个元素的出现次数进行增加更新:

 1 import  collections 2 li = "nihao"  #原始字符串 3 a = collections.Counter(li)  #统计每个元素出现的次数 4 print(a) #打印元素 字符串每个元素出现的次数 5 a.update("hello") #更新字符串元素 6 print(a)  #打印更新后的元素出现次数 7 8 执行结果: 9 Counter({'o': 1, 'i': 1, 'h': 1, 'n': 1, 'a': 1}) #原始的字符串出现次数10 Counter({'o': 2, 'l': 2, 'h': 2, 'i': 1, 'n': 1, 'a': 1, 'e': 1})  #更新后的字符串元素出现次数

5、subtract:对同一个元素做减处理,如下:

 1 import  collections 2 li = "nihao"  #原始字符串 3 a = collections.Counter(li)  #统计每个元素出现的次数 4 print(a) 5 a.subtract("hello") #打印元素 字符串每个元素出现的次数 6 print(a)  #打印更新后的元素出现次数 7 8 执行结果: 9 Counter({'a': 1, 'h': 1, 'o': 1, 'i': 1, 'n': 1}) #更新之前每个元素的出现次数10 Counter({'a': 1, 'i': 1, 'n': 1, 'o': 0, 'h': 0, 'e': -1, 'l': -2}) #更新之后的每个元素的出现次数,与update相反,是对原数据进行减操作,如果元素没有则会标记元素为-1,在减一次为-2,对这个元素update一次则增加为-1,如:11 import  collections12 li = "nihao"  #原始字符串13 a = collections.Counter(li)  #统计每个元素出现的次数14 print(a)15 a.subtract("hello") #打印元素 字符串每个元素出现的次数16 print(a)  #打印更新后的元素出现次数1718 a.update("llo")19 print(a)2021 执行结果:22 Counter({'a': 1, 'o': 1, 'h': 1, 'i': 1, 'n': 1})23 Counter({'a': 1, 'n': 1, 'i': 1, 'o': 0, 'h': 0, 'e': -1, 'l': -2})24 Counter({'a': 1, 'n': 1, 'o': 1, 'i': 1, 'h': 0, 'l': 0, 'e': -1}) #l的次数转正了

6、del:删除指定的元素:会删除元素和元素的计数值:

 1 import  collections 2 li = "nihao"  #原始字符串 3 a = collections.Counter(li)  #统计每个元素出现的次数 4 print(a,"原字符串") 5 a.subtract("heello") #打印元素 字符串每个元素出现的次数 6 print(a,"做减操作的字符串") 7 del a["l"]#打印元素 字符串每个元素出现的次数 8 del a["e"] 9 print(a,"使用del删除元素的字符串")  #打印更新后的元素出现次数1011 执行结果:12 Counter({'i': 1, 'o': 1, 'h': 1, 'n': 1, 'a': 1}) 原字符串13 Counter({'i': 1, 'n': 1, 'a': 1, 'o': 0, 'h': 0, 'l': -2, 'e': -2}) 做减操作的字符串14 Counter({'i': 1, 'n': 1, 'a': 1, 'o': 0, 'h': 0}) 使用del删除元素的字符串,删除后即使该元素的次数为-2也可以只接全部删除元素和元素的出现次数,即会会删除元素本身和其计数

7、get:获取指定元素出现的次数:

1 import  collections2 li = "nihaoiinn"  #原始字符串3 a = collections.Counter(li)  #统计每个元素出现的次数4 print(a.get("n"))  #获取指定元素的出现次数56 执行结果:7 3    #表示n在此字符创当中一共出现了3次

8.copy:是浅copy,浅copy只copy第一层,变量里面包含的列表或字典的id值和以前是不变的:

 1 import  collections 2 li = "nihaoiinn[jack]"  #原始字符串 3 a = collections.Counter(li)  #统计每个元素出现的次数 4 b  = a.copy() 5 print(id(a),"id-->a的id") 6 print(id(b),"id-->b的id") 7 8 print(id(a[9]),"a的第九个元素的id") 9 print(id(b[9]),"b的第九个元素的id")1011 执行结果:12 11335784 id-->a的id13 11337064 id-->b的id14 505605904 a的第九个元素的id15 505605904 b的第九个元素的id

9、defaultdict:默认字典,在创建的时候指定该字典的默认数据格式,可以是列表、元组或列表等,如:

1 import  collections2 dic1 = collections.defaultdict(list)3 dic1["k1"].append(1)4 print(dic1)56 执行结果:7 defaultdict(<class 'list'>, {'k1': [1]}) #默认的数据格式为list,即元素的默认格式为list,可以使用列表的所有操作方法对字典的值进行操作

10.OrderedDict:有序字典,默认创建的字典是无需的,可以使用OrderedDict创建字典,这样字典内部会对key进行排序显示,key的顺序将会固定保持不变,如下:

 1 import  collections 2 d=collections.OrderedDict() 3 d['a']='111' 4 d['b']='222' 5 d['c']='333' 6 for k,v in d.items(): 7     print(k,v) 8 9 执行结果:10 a 11111 b 22212 c 333  #可以看到时按照是按照顺序排列的,而且刷新以后的顺序也会保持不变1314 下面创建一个默认的字典:15 d={}16 d['a']='111'17 d['b']='222'18 d['c']='333'19 for k,v in d.items():20     print(k,v)2122 执行结果:23 c 33324 a 11125 b 222   #不是按照顺序排列的,而且每次刷新的顺序都不一致

有序字典的常用操作:

pop、删除指定的字典key,并返回被删除的value

 1 import  collections 2 dic1 = collections.OrderedDict({'name':'jack','age':20,'job':'IT'}) 3 print(dic1) 4 print(dic1.pop("age")) 5 print(dic1) 6 7 执行结果: 8 OrderedDict([('name', 'jack'), ('job', 'IT'), ('age', 20)]) #删除之前的有序字典 9 20  #被删除的value10 OrderedDict([('name', 'jack'), ('job', 'IT')]) #删除之后的有序字典

keys:获取有序字典的全部key,方法和字典是一样的:

1 import  collections2 dic1 = collections.OrderedDict({'name':'jack','age':20,'job':'IT'})3 print(dic1.keys())45 执行结果:6 odict_keys(['name', 'age', 'job'])

values:获取有序字典所有的值,方法和字典是一样的:

1 import  collections2 dic1 = collections.OrderedDict({'name':'jack','age':20,'job':'IT'})3 print(dic1.values())执行结果:odict_values(['IT', 'jack', 20])  #所有的值

items:获取有序字典所有的键值对,方法和字典是一样的:

1 import  collections2 dic1 = collections.OrderedDict({'name':'jack','age':20,'job':'IT'})3 print(dic1.items())执行结果;odict_items([('name', 'jack'), ('job', 'IT'), ('age', 20)]) #所有的键值对

move_to_end:将指定的键值对移动到最后的位置:

1 import  collections2 dic1 = collections.OrderedDict({'name':'jack','age':20,'job':'IT'})3 dic1.move_to_end("name") #将name移动到最后的位置4 #print(dic1.pop("age"))5 print(dic1)67 执行结果:8 OrderedDict([('age', 20), ('job', 'IT'), ('name', 'jack')])  #顺序已经发生变化,name到最后了

clear:清空有序字典的所有键值对:

1 import  collections2 dic1 = collections.OrderedDict({'name':'jack','age':20,'job':'IT'})3 dic1.clear()4 print(dic1)56 执行结果:7 OrderedDict()  #字典已经为空

11、namedtuple:可命名元组,可以给元组命名,在通过元素的名称获取到元素的值,也可以使用元素的下标获取到元素的值:

1 import  collections2 Mytuple = collections.namedtuple("xy",['a','b'])  # collections.namedtuple表示对一个元素命名,本为名称是xy,名称必须有,其包含有两个元素a和b3 list1 = Mytuple(10,20)  #实例化类,并传递两个参数进去4 print(list1.a)  #打印结果5 print(list1[0])67 #执行结果:8 10   #10是a的值,即可以用元素的名称获取到元素的值9 10 #通过下标获取到的元素的值

12、queue.Queue:单向队列,先进先出,类似于弹夹,先放去的子弹先打出来,只能从左边进行操作:

put,get,qsize,full:插入数据,获取数据,查看队列长度,判断队列是否已经满了:

 1 import  queue 2 d = queue.Queue(maxsize=3) #创建一个队列并指定最大长度为3个 3 d.put("a") #添加一个队列值 4 d.put("b") #添加一个队列值 5 d.put("c") #添加一个队列值 6 print(d.qsize()) #查看队列的当前长度 7 print(d.full()) #先判断队列是否已经满了 8 print(d.get()) #获取一个队列值 9 print(d.get()) #获取一个队列值10 print(d.get()) #获取一个队列值11 print(d.qsize()) #获取完队列值再次查看队列的长度12 print(d.full()) #再次判断队列是否满了1314 执行结果:15 3   #第一次已经显示队列是3个了16 True  #第一次队列是满的17 a18 b19 c #获取三个值20 0  #此时队列里面已经再没有数据了21 False  #之后队列就是空的了

empty:判断队列是否为空,是返回True,否返回False:

 1 import  queue 2 d = queue.Queue(maxsize=3) 3 d.put("a") 4 d.put("b") 5 d.put("c") 6 print(d.qsize()) 7 print(d.get()) 8 print(d.get()) 9 print(d.get())10 print(d.qsize())11 print(d.empty(),"#判断是会否为空")1213 执行结果:14 3  #首次的队列长度15 a16 b17 c #获取三个值18 0  #获取值之后的队列的长度为019 True #判断是会否为空,是返回True,否返回False

put_nowait:在队列可以插入的时候不阻塞插入数据数据,可以理解为不按排队顺序插队到最前面put数据:

get_nowait:在队队列有时间后不阻塞获取数据,可以理解为不按排队顺序插队到最前面get数据:

 1 import  queue 2 d = queue.Queue(maxsize=3) 3 d.put_nowait("a") 4 d.put_nowait("b") 5 d.put_nowait("c") #每获取一次数据,队列的长度减1 6 print(d.qsize()) 7 print(d.get_nowait()) 8 print(d.get_nowait()) 9 print(d.get_nowait())10 print(d.qsize())11 print(d.empty(),"#判断是会否为空")1213 执行结果:14 315 a16 b17 c18 019 True #判断是会否为空

13、queue.deque:双向队列,可以左右两侧都进行操作的队列与单向队列最大的不同是可以从队列左右两侧都进行操作,

appendleft:添加元素到最左侧:

append:添加元素做最右侧,即末尾:

import  queued = queue.deque(["a,","b","c",'d'])print(d)d.append("jack")d.appendleft("tom")print(d)执行结果:deque(['a,', 'b', 'c', 'd'])  #添加之前的队列deque(['tom', 'a,', 'b', 'c', 'd', 'jack'])  #添加之后的队列append,appendleft

count:统计队列中某个元素出现的次数,而不是某个字符串;

copy:是浅copy,只拷贝第一层,其内部包含的元素和列表的id是一样的

 1 import  queue 2 d = queue.deque(["a,","b","tom","c",'d',"tom"]) 3 print(d) 4 print(d.count("tom"),"tom出现了两次,表示队列中的元素可以重名即可以重复") 5 6 a = d.copy() 7 print(id(a),"a的id") 8 print(id(d),"d的id") 9 print((a[3]),"a的第三个元素")10 print(id(a[3]),"a的第三个元素的id")11 print(id(d[3]),"a的第三个元素的id")1213 执行结果:14 deque(['a,', 'b', 'tom', 'c', 'd', 'tom']) 原队列内容15 2 tom出现了两次,表示队列中的元素可以重名即可以重复16 12208024 a的id17 12207920 d的id18 c a的第三个元素19 4803472 a的第三个元素的id20 4803472 a的第三个元素的id

extend:对原队列进行右侧扩展,扩展的元素是是字符串,而append附加是元素,一个元素可以包含多个字符串,如果extend传递的一个包含多个字符串的元素,则会展开元素为多个字符串进行添加:

extendleft:对原队列进行左侧侧扩展,其他同extend

 1 import  queue 2 d = queue.deque(["a,","b","c",'d',"tom"]) 3 print(d) 4 d.extend("jack")  #右侧扩展jack 5 d.extendleft("lyly") #左侧扩展lyly 6 print(d) 7 8 执行结果: 9 deque(['a,', 'b', 'c', 'd', 'tom'])  #扩展之前的队列10 deque(['y', 'l', 'y', 'l', 'a,', 'b', 'c', 'd', 'tom', 'j', 'a', 'c', 'k']) #扩展之后的队列,扩展后会将元素拆开为多个字符串进行添加,与append大为不同

index:根据value获取其下标位:

insert:将元素插入到指定的下标位置:

 1 import  queue 2 d = queue.deque(["a,","b","c",'d',"tom"]) 3 print(d) 4 d.insert(1,"jack") 5 print(d.index("jack")) 6 print(d) 7 8 执行结果: 9 deque(['a,', 'b', 'c', 'd', 'tom'])  #insert之前的队列10 1 #获取到的jack的下标位置11 deque(['a,', 'jack', 'b', 'c', 'd', 'tom'])  #打印insert之后的队列结果

reverse:将整个队列顺序反转显示,即倒数第一个为第一个,倒数第二个为第二个,一次类推

rotate:将最后指定数量的几个元素放在最前的位置

 1 import  queue 2 d = queue.deque(["a,","b","c",'d',"tom"]) 3 print(d) #原队列顺序 4 d.reverse()  #将整个队列顺序反转显示,即倒数第一个为第一个,倒数第二个为第二个,一次类推 5 print(d) #反转整个队列之后的结果 6 7 a = queue.deque(["a,","b","c",'d',"tom"])  #将最后指定数量的几个元素放在最前的位置 8 print(a)  #原队列顺序 9 a.rotate(2)  #反转两个元素10 print(a)  #反转2个元素之后的结果

pop:从右侧删除元素并返回被删除的元素

popleft:从左侧删除元素并返回被删除的元素

 1 import  queue 2 d = queue.deque(["a,","b","c",'d',"tom"]) 3 print(d) #原队列顺序 4 print(d.pop())  #删除右侧第一个元素 5 print(d) #删除左右侧第一个元素之后的结果 6 7 a = queue.deque(["a","b","c",'d',"tom"]) 8 print(a)  #原队列顺序 9 print(a.popleft())  #删除最左侧的元素10 print(a)  #删除最左侧第一个元素之后的结果1112 执行结果:13 deque(['a,', 'b', 'c', 'd', 'tom'])14 tom  #被删除的右侧元素15 deque(['a,', 'b', 'c', 'd']) #删除右右侧第一个元素之后的结果16 deque(['a', 'b', 'c', 'd', 'tom'])17 a  #被删除的左侧元素18 deque(['b', 'c', 'd', 'tom'])  #删除最左侧第一个元素之后的结果

remove:根据value删除元素

clear:清空整个队列

 1 import  queue 2 d = queue.deque(["a,","b","c",'d',"tom"]) 3 print(d," #原队列顺序") 4 print(d.remove("d"),"#删除指定的value d") 5 print(d,"#删除d之后的结果") 6 7 a = queue.deque(["a","b","c",'d',"tom"]) 8 print(a," #原队列顺序") 9 print(a.clear(),"#清空队列")10 print(a," #清空队列之后的结果")1112 执行结果:13 deque(['a,', 'b', 'c', 'd', 'tom'])  #原队列顺序14 None #删除指定的value d15 deque(['a,', 'b', 'c', 'tom']) #删除d之后的结果16 deque(['a', 'b', 'c', 'd', 'tom'])  #原队列顺序17 None #清空队列18 deque([])  #清空队列之后的结果

二:深浅copy:

copy:称为浅copy,默认的copy都是浅coyp,即没有特定使用深copy的操作,浅copy只copy第一层,即不copy内部的列表、字典或元组(假如有以上元素),可以用元素的id区分

deepcopy:深copy,会copy每一层的元素,包含copy内部的元组、字段或列表

假如copy对象都是字符串:

 1 import  copy 2 #a = [123,"a","b","c",456,("tom",["it","18"]),{"jack":{"age":12}}] 3 a = "123456abcd" 4 b = copy.copy(a) 5 c = copy.deepcopy(a) 6 print(a) 7 print(b) 8 print(c) #每个变量的内容 9 print(id(a))10 print(id(b))11 print(id(c))  #每个变量的id12 print(id(a[4]))13 print(id(b[4]))14 print(id(c[4]))  #每个变量的同一个元素的id值1516 执行结果:17 123456abcd18 123456abcd19 123456abcd  #三个变量的值20 754955221 754955222 7549552  #三个变量的id是相同的23 745436824 745436825 7454368 #三个变量的同一个元素的id也是相同的

假如copy对象有列表并修改列表的值:

 1 import  copy 2 a = [123,"a","b","c",456,["tom",["it","18"]],{"jack":{"age":12}}] 3 b = copy.copy(a) #b是浅copy的a的值,可以简写为b = a 4 c = copy.deepcopy(a) #c是深copy的a的值 5 print(a) #a的内容 6 print(b) #b的内容 7 print(c) #c的内容 8 #############查看第一层的元素的id 9 print(id(a))  #a的id10 print(id(b)) #b的id11 print(id(c))  #c的id12 #############查看第二层的元素的id13 print(c[5])  #获取一个元素14 print(id(a[5])) #a的第5个元素的id值15 print(id(b[5])) #b是浅copy,查看b的第5个元素的id值16 print(id(c[5]))  #c是深copy,查看c的第5个元素的id值1718 #############查看第三层的元素id19 print(c[5][0])  #第5个元素的是一个元组,获取到该元组的第一个元素是tom20 print(id(a[5][0])) #查看元组中的元素的ID值21 print(id(b[5][0])) #查看元组中的元素的ID值22 print(id(c[5][0])) #查看元组中的元素的ID值232425 执行结果:26 [123, 'a', 'b', 'c', 456, ['tom', ['it', '18']], {'jack': {'age': 12}}]  #a的内容27 [123, 'a', 'b', 'c', 456, ['tom', ['it', '18']], {'jack': {'age': 12}}] #b的内容28 [123, 'a', 'b', 'c', 456, ['tom', ['it', '18']], {'jack': {'age': 12}}] #c的内容29 14771656 #第一层原a的id30 11150920 #第一层浅copy之后b的id,可以发现包含了列表之后和a的id也不一样了,上个例子如果只是字符串还是一样的31 14772168  #第一层深copy之后c的id32 ('tom', ['it', '18']) #获取到第二层的元素33 11060424 #a第二层的元素id34 11060424 #b第二层的元素id35 11079624 #c第二层的元素id36 tom  #第三层的元素37 11048360  #a的第三层的元素id38 11048360 #b的第三层的元素id39 11048360 #c的第三层的元素id  #可以发现最底层的元素id是一样的,最底层是把元素做了链接404142 #############修改copy源的第三层的元素的值,再看深浅copy的自底层的元素值:43 a[5][1][0] = "CTO"  #此元素为修改之前为it44 print(id(a[5][0])) #查看元组中的元素的ID值45 print(id(b[5][0]))46 print(id(c[5][0]))4748 执行结果:49 14390696  #a修改第三层后的第三层元素的id50 14390696  #修改后b也发生变化51 14390696  #a也发生了变化,可见深copy之后最底层的元素是链接到了a的最底层之上,这样节省空间也免去了copy的步骤从而节约了时间525354 #############修改深copy之后的元素的值,查看a和b是否受影响:55 print("###########")56 c[5][1][0] = "CTO" #为指定元素重新赋值57 print(c[5][1][0])  #打印修改后的元素的结果,验证是否修改成功58 print(id(a[5][0])) #查看修改后a的此元素的值59 print(id(b[5][0])) #查看修改后b的此元素的值,6061 执行结果:62 CTO63 1209693664 1209693665 12096936 #以上id都是一样的,可见修改深copy之后最底层的值,会影响到copy源本身和浅copy之后的值666768 #############修改浅copy之后的元素的值,查看a和b是否受影响:69 b[5][1][0] = "CTO"70 print(b[5][1][0])71 print(id(a[5][0])) #查看元组中的元素的ID值72 print(id(b[5][0]))73 print(id(c[5][0]))7475 执行结果:76 CTO77 1432516078 1432516079 14325160  #三个元素的id是一样的,可见即使修改浅copy的底层元素的值也会影响到copy源本身和身copy的元素id值

假如copy对象是字典:

 1 import  copy 2 a = {"CPU":[80],"MEM":[80],"Disk":[80],} 3 b = copy.copy(a) 4 c = copy.deepcopy(a) 5 6 print(a,"a原字典") 7 print(b,"b浅copy原字典") 8 print(c,"c深copy原字典") 9 print(id(a),"原字典的id")10 print(id(b),"浅copy的id")11 print(id(c),"深copy的id")121314 #############################修改copy源15 a["CPU"][0] = 50 #对copy源的元素值做修改16 #print(["CPU"][0])17 print(id(a["CPU"][0]),"原字典的元素id")18 print(id(b["CPU"][0]),"浅copy的元素id")19 print(id(c["CPU"][0]),"深copy的元素id")20 print(a["CPU"][0],"原元素")21 print(b["CPU"][0],"浅copy元素值")22 print(c["CPU"][0],"深copy元素值")2324 执行结果:25 {'MEM': [80], 'Disk': [80], 'CPU': [80]} a原字典26 {'MEM': [80], 'Disk': [80], 'CPU': [80]} b浅copy原字典27 {'MEM': [80], 'Disk': [80], 'CPU': [80]} c深copy原字典28 13825672 原字典的id29 14370696 浅copy的id30 14271368 深copy的id31 493417808 原字典的元素id32 493417808 浅copy的元素id33 493418768 深copy的元素id34 50 原元素35 50 浅copy元素值,可见修改字典类型的copy源会影响其本身和浅copy的元素值,不会影响到深copy,这是因为浅copy只是copy了表面,内部是做的链接36 80 深copy元素值,深copy对于字典是从第一层到最末一层完全copy的,没有使用链接373839 ###########################修改浅copy的元素值40 b["CPU"][0] = 50 #对浅拷贝之后的CPU的值做修改,b是浅copy41 print(id(a["CPU"][0]),"原字典的元素id")42 print(id(b["CPU"][0]),"浅copy的元素id")43 print(id(c["CPU"][0]),"深copy的元素id")44 print(a["CPU"][0],"原元素")45 print(b["CPU"][0],"浅copy元素值")46 print(c["CPU"][0],"深copy元素值")4748 执行结果:49 {'MEM': [80], 'Disk': [80], 'CPU': [80]} a原字典50 {'Disk': [80], 'CPU': [80], 'MEM': [80]} b浅copy原字典51 {'Disk': [80], 'CPU': [80], 'MEM': [80]} c深copy原字典52 6289032 原字典的id53 11224968 浅copy的id54 11125640 深copy的id55 503051600 原字典的元素id56 503051600 浅copy的元素id57 503052560 深copy的元素id58 50 原元素59 50 浅copy元素值60 80 深copy元素值,可见修改浅copy影响的范围和修改copy源本身的范围是一样的,只会影响copy源和浅copy,深copy不受其影响616263 #############################修改深copy的元素值64 c["CPU"][0] = 50 #对深拷贝之后的CPU的值做修改,c是深copy65 print(id(a["CPU"][0]),"原字典的元素id")66 print(id(b["CPU"][0]),"浅copy的元素id")67 print(id(c["CPU"][0]),"深copy的元素id")68 print(a["CPU"][0],"原元素")69 print(b["CPU"][0],"浅copy元素值")70 print(c["CPU"][0],"深copy元素值")7172 执行结果:73 {'Disk': [80], 'MEM': [80], 'CPU': [80]} a原字典74 {'Disk': [80], 'MEM': [80], 'CPU': [80]} b浅copy原字典75 {'Disk': [80], 'MEM': [80], 'CPU': [80]} c深copy原字典76 13760136 原字典的id77 14305160 浅copy的id78 14205832 深copy的id79 499448080 原字典的元素id80 499448080 浅copy的元素id81 499447120 深copy的元素id82 80 原元素83 80 浅copy元素值84 50 深copy元素值,可见深copy只影响深copy本身,不影响copy源和浅copy,由此可以断定深copy对于字典是完全copy,包括key和value都是完全copy一份,copy完之后就和copy源没有任何关联了。

深浅copy总结:

1、假如copy源只是字符串,则深浅copy没有区别,只是copy后变量名称的id值不一样,其内部的元素的id值是一致的。

2、假如copy是列表组成,则会将内部的列表完全copy一份,其内部的元素的id会指向copy源的底层元素,假如对元素做了一份浅copy和深copy,则无论是修改了copy源的底层元素、浅copy的底层元素还是深copy的底层元素,都会影响到元素本身和其他copy的元素改变。

 3、假如copy源是字典,则深会对字典的key和value完全copy,浅copy依然是对内部的元素做链接到copy源,修改copy源和浅copy只会影响浅copy源和浅copy,不会影响到深copy,同样修改深copy也不会影响到以上浅copy和浅copy源本身。

三:yield 和return:

yield:是一个生成器,在函数里用于记住上一次的操作,下次在执行的时候从当前的位置继续执行,生成器生成的值需要用for循环才能访问到:

 1 def func(arg): 2     print(arg,"第一次") 3     yield "a" #以实参作为返回值 4     print(arg,"第二次") 5     yield "b" 6 a = func("a") 7 for i in a: 8     print(i) 910 执行结果:11 a 第一次12 a  #第一次yield的值13 a 第二次14 b  #第二次yield的值1516 #在整个函数运行的时候,先进入到函数内部,执行 print(arg,"第一次")之后遇到yield "a"并执行后返回到for循环print(i),然后再从for循环跳转到函数内部执行print(arg,"第二次")和yield "b",即在函数内部遇到yield会暂停函数内部运行,跳出后遇有调用的时候在从跳出的yield位置继续运行。

return:函数的返回值,遇到return的时候函数会停止继续运行,并以return的返回值赋值给函数本身,一个函数只能有一个return,多余的也不会执行,因为第一个return之后函数就停止运行了。

1 def func():2     name = "jack"3     return name4     age = 185     return  age6 print(func())  #打印函数的值,返回值会赋值给函数的名称调用78 执行结果:9 jack    #遇到return跳出后就停止运行函数,并就此终止函数,因此不会执行age的代码

四:集合(set)

set的元素是不能重复出现的,而且是无序排列的,如创建一个包含重复字串的集合:

1 set1 = set("abcdefgabc")2 print(set1)34 执行结果;5 {'g', 'c', 'd', 'b', 'e', 'a', 'f'} #可见是无序排列并将元素拆分为单个字串,并将重复的abc只显示了单个

set的常用操作方法:

add:向集合里面添加元素:

remove:删除指定的元素名,且没有返回值

pop:随机删除集合的元素并返回被删除的值

 1 set1 = set("abcbdefgabc") 2 set1.add("tom") 3 print(set1) 4 print(set1.remove("b"),"remove删除元素需指定要删除的元素名称,且没有返回") 5 print(set1) 6 print(set1.pop(),"pop删除元素无需参数,切会返回删除的元素") 7 print(set1) 8 9 执行结果:10 {'g', 'e', 'd', 'b', 'a', 'tom', 'c', 'f'}  #添加tom以后的集合11 None  #remove删除元素需指定要删除的元素名称,且没有返回,返回为None12 {'g', 'e', 'd', 'a', 'tom', 'c', 'f'} #remove删除元素以后的集合13 g  #pop删除元素无需参数,切会返回删除的元素,本次为g14 {'e', 'd', 'a', 'tom', 'c', 'f'} #pop删除元素以后集合

clear:清空元素列表:

copy:浅copy为另一个集合:

update:更新现有的集合:

 1 set1 = set("abcbdefgabc") 2 print(set1,"set1原来的集合效果") 3 set1.update("tom") 4 print(set1,"updatede的tom的效果") 5 6 print("##########################") 7 set2 = set1.copy() 8 print(id(set2)) 9 print(id(set1))101112 print("##########################")13 set3 = set("abcbdefgabc")14 print(set3,"set3原来的集合效果")15 set3.clear()16 print(set3,"set3的clear的效果")1718 执行结果:19 {'f', 'e', 'g', 'a', 'b', 'c', 'd'} set1原来的集合效果20 {'o', 'f', 'e', 'g', 'a', 'b', 'c', 'd', 't', 'm'} updatede的tom的效果21 ##########################22 14111688  #浅copy之前的set1的id23 10215208  #浅copy之后的set3的id24 ##########################25 {'f', 'e', 'g', 'a', 'b', 'c', 'd'} set3原来的集合效果26 set() set3的clear的效果

difference:用两个集合作比较,删除传递的参数并生成一个新的集合,只返回非传递的集合里没有的元素,并生成一个新的序列,如:

1 set1 = set("abcd")2 set2 = set("abc")3 set3 = set1.difference(set2)4 print(set3)56 执行结果;7 {'d'}  #返回set1有而set2没有的元素,本次为d

difference_update:删除原集合有并且传递的集合都有的值,这是在原集合直接操作的,删除完成以后查看原集合的值是否有变化:

1 set1 = set("abcd")2 set2 = set("abce")3 set1.difference_update(set2)4 print(set1)56 执行结果;7 {'d'}  #删除完成之后set1就只有一个d了,因为abc和在set2里面也,被删除了

discard:丢弃一个指定的元素:

1 set1 = set("abcd")2 set1.discard("c")  #丢弃c3 print(set1)45 执行结果:6 {'a', 'd', 'b'}

intersection:交集运算,即取原集合和传递的集合共同都有的元素,并产生一个新的set集合:

1 set1 = set("abcd")2 set2 = set("abce")3 set3 = set1.intersection(set2)  #取set1和set2共同含有的元素并赋值给set34 print(set3)56 执行结果:7 {'c', 'a', 'b'} #abc是set1和set2共同含有的元素

intersection_update:交集运算,即取原集合和传递的集合共同都有的元素,并直接赋值给原集合:

1 set1 = set("abcd")2 set2 = set("abce")3 set1.intersection_update(set2)  #取set1和set2共同含有的值并赋值给set14 print(set1)56 执行结果;7 {'b', 'a', 'c'}  #set1的值已经成为abc了

isdisjoint:判断是否没有交集,即判断是否没有同样的元素,没有返回True,有返回False:

1 set1 = set("abcd")2 set2 = set("qwer")3 print(set1.isdisjoint("aoiu"))4 print(set1.isdisjoint(set2))56 执行结果:7 False  #set1与aoiu有共同的元素a,所以返回False8 True  #set1与set2没有共同的元素,所以返回True

issubset:判断是否子集,即原集合是否传递集合的子集:

1 set1 = set("abcd")2 set2 = set("abcdefg")3 print(set1.issubset(set2))4 print(set1.issubset("abcdefg"))56 执行结果:7 True #set1是set2的子集8 True #set1是字符串abcdefg的子集

issuperset:与issubset相反,判断是否父集:

1 set1 = set("abcd")2 set2 = set("abcdefg")3 print(set2.issuperset(set1))4 print(set1.issuperset("abcdefg"))56 执行结果:7 True #set2是set1的父集8 False #set1不是abcdefg的父集

symmetric_difference:取出来两个集合相互没有的元素,并将结果赋值给一个新的集合:

1 set1 = set("abcdiop")2 set2 = set("abcdefg")3 set3 = set2.symmetric_difference(set1)  #取出来两个集合相互没有的元素并赋值给set34 print(set3)56 取差集:7 {'g', 'e', 'i', 'f', 'p', 'o'}  #取出来两个集合相互没有的元素

symmetric_difference_update:取出来两个集合相互没有的元素,并将结果赋值给原集合而不是赋值给一个新的集合:

1 set1 = set("abcdiop")2 set2 = set("abcdefg")3 set1.symmetric_difference_update(set2)  #取两个集合相互都没有的元素并就地赋值给原集合set14 print(set1)56 执行结果;7 {'p', 'e', 'g', 'f', 'o', 'i'}  #这就是set1的值,是取出两个集合相互没有的元素

union:去两个几个的并集,等于将两个集合的元素全部取出来并去重,最终每个元素只留一个:

1 set1 = set("abc")2 set2 = set("abg")3 set3 = set1.union(set2)4 print(set3)56 执行结果:7 {'a', 'g', 'b', 'c'}   #结果是每个元素都有而且每个元素只有一个的新的集合

有一个数据,需要通过集合的方式计算出需要更新、添加和删除的数据,最终要求是原来的没有新数据有就添加,原来有新的也有就更新,原来有新的没有删除,具体如下:

old_dict = {    "#1":{ 'hostname':"c1", 'cpu_count': 2, 'mem_capicity': 80 },    "#2":{ 'hostname':"c2", 'cpu_count': 2, 'mem_capicity': 80 },    "#3":{ 'hostname':"c3", 'cpu_count': 2, 'mem_capicity': 80 },}new_dict = {    "#1":{ 'hostname':"c2", 'cpu_count': 2, 'mem_capicity': 80 },    "#3":{ 'hostname':"c3", 'cpu_count': 2, 'mem_capicity': 80 },    "#4":{ 'hostname':"c4", 'cpu_count': 2, 'mem_capicity': 80 },}old = set(old_dict.keys())  #就的数据keynew = set(new_dict.keys())  #新的数据keyupdate_set = old.intersection(new)  #交集运算,取出old和new共同含有的元素,并赋值给update_set,共同都有的数据是要更新的数据delete_set = old.difference(update_set)  #要删除的数据,用旧的数据删除要两边都有的数据,即得到要删除的数据add_set = new.difference(update_set)  #要更新的数据,for i in update_set:  #循环要更新的数据    print("要更新的数据是%s" % i)    old_dict[i] = new_dict.get(i)  #将新的数据赋值给旧的字典,    print(old_dict,"更新数据的字典")for i in delete_set:    print("要删除的数据是%s" % i)    old_dict.pop(i)  #删除指定的要删除的数据    print(old_dict,"删除数据的字典")for i in add_set:    print("要添加的数据是%s" % i)    old_dict[i] = new_dict.get(i)    print(old_dict)执行结果:要更新的数据是#1{'#1': {'cpu_count': 2, 'mem_capicity': 80, 'hostname': 'c2'}, '#3': {'cpu_count': 2, 'mem_capicity': 80, 'hostname': 'c3'}, '#2': {'cpu_count': 2, 'mem_capicity': 80, 'hostname': 'c2'}} 更新数据的字典要更新的数据是#3{'#1': {'cpu_count': 2, 'mem_capicity': 80, 'hostname': 'c2'}, '#3': {'cpu_count': 2, 'mem_capicity': 80, 'hostname': 'c3'}, '#2': {'cpu_count': 2, 'mem_capicity': 80, 'hostname': 'c2'}} 更新数据的字典要删除的数据是#2{'#1': {'cpu_count': 2, 'mem_capicity': 80, 'hostname': 'c2'}, '#3': {'cpu_count': 2, 'mem_capicity': 80, 'hostname': 'c3'}} 删除数据的字典要添加的数据是#4{'#1': {'cpu_count': 2, 'mem_capicity': 80, 'hostname': 'c2'}, '#3': {'cpu_count': 2, 'mem_capicity': 80, 'hostname': 'c3'}, '#4': {'cpu_count': 2, 'mem_capicity': 80, 'hostname': 'c4'}}

 五:模块变量:

__main__:判断是不是执行的主文件,当前文件为主执行文件的时候,其变量 __name__的名为__main__,如果有其他的模块或文件被调用到此文件,则其他的文件或模块的名称不会为__main__。

 1 def func(arg): 2     print("func1",arg) 3 4 if __name__ == "__main__": 5     func(123) 6     print(__name__) #当前文件为主执行文件的时候,其文件名为__main__,其他被调用的文件名 7 8 执行结果: 9 func1 12310 __main__  #打印name的值

vars() :当前模块的所有变量,file-当前文件的路径、doc-最开始的三个引号的注释

1 print(vars())23 执行结果:4 {'__doc__': '\nimport  collections\nobj = collections.Counter("asdasdasdasdtghtiotl")\nprint(obj)\n\n\n', '__package__': None, '__file__': '/Users/zhangshijie/PycharmProjects/S12-Python3/Day3/s1.py', '__spec__': None, '__cached__': None, '__name__': '__main__', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x1007a5be0>, '__builtins__': <module 'builtins' (built-in)>}

reload(os) #执行程序的时候,重新读取python的模块,用于对模块进行修改的情况

典型的python文件结构图:

六:内置函数:

python安装好之后会有很多内置函数模块已经配置好并且可以按需调用,

all:所有的值都不为false,则整个变量才True,可用于判断用户输入是否完整:

print(all([]),"#空的列表结果为True")print(all(["a",""]),"有一个空值的列表结果为False")print(all(["a",0]),"有一个值为0的列表结果为False")print(all(()),"空元组结果为True")print(all({}),"空的字典结果为True")print(all([""]),"#列表有一个空的元素,结果为False")print(all(["a","b",1,0]),"#要所有的元素都为真,结果才为True,而0等于假,所以结果为False")print(all({"name":[]}),"value为空的字典也为True")print(all({"name":0}),"value为0的字典也为True")执行结果:True #空的列表结果为TrueFalse 有一个空值的列表结果为FalseFalse 有一个值为0的列表结果为FalseTrue 空元组结果为TrueTrue 空的字典结果为TrueFalse #列表有一个空的元素,结果为FalseFalse #要所有的元素都为真,结果才为True,而0等于假,所以结果为FalseTrue value为空的字典也为TrueTrue value为0的字典也为True

abs() #返回一个数值的绝对值

1 >>> abs(-9)2 9

any:与all函数作用相反,如果任何迭代的一个元素为ture,或者为空,则返回false

ascii: 转成ascii码

bin:转一个整数得到一个二进制的字符串

bool:转换一个值,得到一个bool类型

bytearray:返回一个字节数据

bytes: 根据一个编码转换成字节形式

callable: 回调函数,如果返回false,则代表回调失败,如果为true,它也仍然可能失败

chr:返回一个整形数字的Unicode形式,比如97返回a

classmethod:为函数返回一个类方法

compile:编译一个资源进入一个代码里或一个AST对象

complex:创建一个复数的表达式

delattr:移除一个对象的属性

dict:创建一个词典结构(类似Map)

dir:如果没有参数返回本文件的路径,如果有参数返回一个对象的属性列表

divmod:两个整形数字做相除

enumerate:可用于指定起始num的排序,如:

 1 list1 = ["沙发","彩电","手机","Mac","汽车"] 2 for i in enumerate(list1,1): 3     print(i) 4 5 执行结果: 6 (1, '沙发') 7 (2, '彩电') 8 (3, '手机') 9 (4, 'Mac')10 (5, '汽车')

eval:执行一个表达式,或字符串作为运算

exec:支持python代码的动态执行

filter:在一个元组里面过滤出目标字符串

float:字符串转成浮点类型

format:格式化字符串

frozenset:返回一个新的克隆对象

getattr:获取对象的一个方法的结果,类似于x.foobar

globals: 返回当前全局的字典表

hasattr:判断是否有某个属性值,返回true代表有

hash:取一个对象的hash值

help:调用系统内置的帮助系统

hex:转换一个整形数字,为小写的十六进制

id: 返回一个对象的唯一标识值

input:从控制台读取数据

int,转换字符串为int型

isinstance:判断一个对象是否为该类的一个实例

issubclass:判断一个类是否为另一个类的子类

iter: 返回一个可迭代的对象

len: 返回一个字符串的长度

list:打印一个集合对象

locals:更细并返回一个词典的本地标志表

map:返回一个可迭代的map函数

max:返回集合里面最大的一个或多个值

memoryview:返回一个python对象的内部数据

min:返回集合里面最小的一个或多个值

next:返回集合里面的下一项数值

object:返回一个新的对象,是所有的类的父类

oct:返回一个整形为八进制类型

open: 打开一个系统文件

ord:得到一个字符串或unicode类型的ascii数值

pow:返回的数字n次方值

print:打印输出语句

property:返回一个属性值

range:产生一个数字序列

repr:返回一个字符串可打印对象

reversed:反转一个集合

round:返回一个四舍五入的浮点数

set:返回一个新的set对象

setattr:设置一个新的属性值

slice:返回一个集合的区间集合

sorted:对一个集合进行排序

staticmethod:声明返回一个静态方法

str:将数字类型转换为字符串

sum:对一个集合里面的值求和

super:返回一个代理父类的对象

tuple:返回一个不可变的元组

type:返回一个对象的类型

vars:返回对象的属性

zip:返回组合一个对等的项

__import__: 比import高级的导入方法

quit,exit,copyright,license,credits