Dq的方法自己要学着看一下。
Dq也是c语言写的性能非常的高。
deque双端队列
list和deque通常被当作容器,存储相同类型元素;tuple通常被当作一个类对象,存储不同类型元素
deque创建:
deque(iterable)(list, tuple, dict都是iterable的,传入dict时key作为deque中的元素)
deque方法:
pop(),popleft(),index(),clear(),insert(),remove(),extend(),extendleft(),count()...
最关键的:
deque是线程安全的(多线程编程时,往里put元素无需加锁),list不是线程安全的
deque是双端队列,可以对两端进行操作。
初始化队列:
ulist = deque(("xxx1","xxx2")),参数接收一个可迭代对象,
尽量用deque保存相同类型的数据
方法:append加到队列尾部、appendleft加到队列头部
copy浅拷贝,队列里面有不可变元素会直接赋值,可变元素(例如列表)会直接指向原来地址
extend在原来元素上动态扩容,接收可迭代对象
extendleft
insert(索引,元素)
pop、popleft、remove、reverse
应用场景:
python3里,from queue import Queue
Queue里面实际上是通过双端队列完成(put方法调用是append,get方法调用的是popleft)
多线程:deque是线程安全的(由GIL保护的),list非线程安全
deque双端队列
线程安全
直接赋值,浅拷贝,深拷贝的区别
# copy()方法 # 浅拷贝,拷贝的是元素,当有地址时拷贝地址 import copy mydeque1 = deque([1,[2,3],4,[5,6]]) mydeque2 = mydeque1.copy() # 浅拷贝 (这是deque的copy不是copy库的) mydeque3 = mydeque1 # 直接复制,指向mydeque1 mydeque4 = copy.deepcopy(mydeque1) # 深拷贝,完全不会随着变化 # 1赋新值 mydeque1[0] = 9 # mydeque2不变,mydeque3变 #[2,3]增加 mydeque1[1].append(8) # mydeque2,mydeque3都跟着变, #[5,6]赋新值 mydeque1[3] = [9,9] # 改变指向地址,mydeque3变 print(mydeque1,mydeque2,mydeque3,mydeque4)
out:
deque([9, [2, 3, 8], 4, [9, 9]]) # mydeque1 deque([1, [2, 3, 8], 4, [5, 6]]) # mydeque2 deque([9, [2, 3, 8], 4, [9, 9]]) # mydeque3 deque([1, [2, 3], 4, [5, 6]]) # mydeque4
""" deque() 双端队列,是一个容器 ,它接收一个可迭代的对象,这个对象可以是列表,元组,字典等 用来保存同类型的内容,可以把它当作一个对象来处理 deque包含的方法: append(): 添加数据到队列 appendleft(): 添加数据到队列头部 clear(): 清空队列数据 copy(): 返回一个浅拷贝,浅拷贝只拷贝元素 count(): 返回队列中元素的数量 extend(): 将两个deque合并为一个 extendleft(): 从左边进行合并 index(): 查找元素 insert(): 在指定位置插入元素 pop(): 移除队列的尾部元素 popleft(): 移除队列的头部元素 remove(): 删除某个元素 reverse(): 将队列反转 deque 是线程安全的,由GIL保护 list 不是线程安全的 """ from collections import deque import copy # 深拷贝 if __name__ == "__main__": user_list = ["张三","李四","王五", "赵六"] user_name = user_list.pop() # 队尾出队 print(user_name, user_list) print("----------------------------") user_tuple = deque(("张三", "李四")) # 初始化 print(user_tuple) user_list = deque(["赵六", "王八"]) print(user_list) user_dict = deque({ "苹果": 12, "雪梨": 15 }) print(user_dict) print("-------------------------") user_info_list = deque(["依依", 23, 171]) user_info = ("C罩杯", "北京大学", "中国北京") user_info_list.append(user_info) # 添加元素 print(user_info_list) print("--------------") name_deque = deque(["苹果", "香蕉", "橘子"]) name_deque.append("芒果") # 添加元素到队列尾部 name_deque.appendleft("哈密瓜") # 添加元素到队列头部 print(name_deque) fruits_deque = name_deque.copy() # 浅拷贝 print(fruits_deque) print(id(fruits_deque) , id(name_deque)) name_deque[1] = "西瓜" print(fruits_deque, name_deque) print("------------------------") color_deque = deque(["yellow","red", "blue", "black", "red"]) print(color_deque) print("元素个数:",color_deque.count("red")) color_deque.pop() # 队尾元素出队 print(color_deque) color_deque.popleft() # 队列头部元素出队 print(color_deque) color_deque.insert(0, "green") # 队列的0号位置插入元素 print(color_deque) color_deque.remove("red") # 移除值为 red的元素 print(color_deque) color_deque.reverse() # 反转队列 print(color_deque) print(color_deque[1]) # 获取下标为1的元素
实例: from collections import deque list_t = ["tom_l", "jane_l", "bob_l"] tuple_t = ("tom_t", "jane_t", "bob_t") dict_t = { "tom_d": "male", "jane_d": "female", "bob_d": "male" } deq = deque(dict_t) deq.append("tim") deq.appendleft("lewin") deq.extend(tuple_t) deq.extendleft(list_t) deq.popleft() deq.pop() deq.remove("lewin") deq.reverse() print(deq.index("tim")) print(deq)
deque 是线程安全的,list不是线程安全的。
浅拷贝只是拷贝了列表中每个元素指向的位置,而不会拷贝如可变对象的所有内容
user_list = ["bobby", "bobby2"] user_name = user_list.pop() #pop只能对队尾进行操作 print(user_name, user_list) #-->bobby2 ["bobby"] #deque双端队列:对队列两端进行操作,尽量保存相同类型数据 from collections import deque user_tuple = deque(("bobby1", "bobby2")) user_list = deque(["bobby1", "bobby2"]) user_dict = deque({"bobby1":28, "bobby2":29}) #以上三种打印结果一样:deque(['bobby1', 'bobby2']) user_deque = deque(["bobby1", "bobby2", "bobby3"]) user_deque.appendleft("bobby8") #在队列头部添加 #deque是线程安全的,list不是
深拷贝:将拷贝的数据和数据的类型都拷贝
深拷贝的意思就是会为引用类型的数据也拷贝一份