python有序队列_python之单例模式、栈、队列和有序字典

本文详细介绍了Python中的单例模式,包括无属性共享、属性共用和线程安全的实现方式。接着讨论了栈(自定义和Python内置LifoQueue)和队列(普通队列与双端队列deque)的数据结构。最后,文章讲解了有序字典OrderedDict的使用,并提到了namedtuple和defaultdict这两个实用的数据结构工具。
摘要由CSDN通过智能技术生成

一、单例模式

1、常用的单例模块

classSingleton(object):_instance =Nonedef __new__(cls, *args, **kwargs):if not cls._instance:

cls._instance = super(Singleton, cls).__new__(cls)return cls._instances1=Singleton()

s2=Singleton()print(s1 is s2) #True

2、属性共用的单例

"""上面的第一种写法,虽然创建的是同一个实例,

但是属性是不共用的,因为每次__init__都会重新设置"""

classSingleton(object):

_instance=Nonedef __new__(cls, *args, **kwargs):if notcls._instance:

cls._instance= super(Singleton, cls).__new__(cls)returncls._instancedef __init__(self, name, age):

self.name=name

self.age=age

s1= Singleton(name="小明", age=18)print(s1.name, s1.age) #小明 18

s2= Singleton(name="小红", age=17)print(s2.name, s2.age) #小红 17

print(s1 is s2) #True

"""因此想要属性也共用,__init__也需要处理"""

classSingleton(object):

_instance=None

_initialized=Falsedef __new__(cls, *args, **kwargs):if notcls._instance:

cls._instance= super(Singleton, cls).__new__(cls)returncls._instancedef __init__(self, name, age):if notself._initialized:

self.name=name

self.age=age

self._initialized=True

s1= Singleton(name="小明", age=18)print(s1.name, s1.age) #小明 18

s2= Singleton(name="小红", age=17)print(s2.name, s2.age) #小明 18

print(s1 is s2) #True

3、加锁的单例

importtimeimportthreadingclassSingleton(object):

lock= threading.RLock() #定义一把锁

_instance =Nonedef __new__(cls, *args, **kwargs):ifcls._instance:return cls._instance #如果之前实例化过,没必要再次实例化,因为都是同一个实例

with cls.lock:#避免当线程没有返回实例前,另一个线程也进来了,导致出现不止一个实例

if notcls._instance:

cls._instance= super(Singleton, cls).__new__(cls)returncls._instancedeftask(arg):

obj=Singleton()print(obj)for i in range(10):

t= threading.Thread(target=task,args=(i,))

t.start()

time.sleep(10)

obj= Singleton()

4、单例装饰器

defsingleton(cls):

_instance={}def _singleton(*args, **kwargs):if cls not in_instance:

_instance[cls]= cls(*args, **kwargs)return_instance[cls]return_singleton

@singletonclassA():def __init__(self, name):

self.name=name

a1= A("ming")print(a1.name) #ming

a2= A("dong")print(a2.name) #ming

二、栈

1、自定义一个栈

#栈是后进先出的数据结构,但是python中并没有栈这种数据结构,因此我们自己实现

classStack(object):def __init__(self):

self.MyStack=[]defpush(self, value):"""向栈插入数据

:param value:

:return:"""self.MyStack.append(value)defpop(self):"""从栈中取走数据

:return:"""

returnself.MyStack.pop()

stack=Stack()

stack.push(1)

stack.push(2)print(stack.pop()) #2

2、python中的栈

后进先出(栈)from queue importLifoQueue

lq=LifoQueue()

lq.put(1)

lq.put(2)

lq.put(3)print(lq.get()) #3

print(lq.get()) #2

print(lq.get()) #1

三、队列

1、python默认的队列

#队列(queue)是一种具有先进先出特征的线性数据结构,元素的增加只能在一端进行,元素的删除只能在另一端进行。能够增加元素的队列一端称为队尾,可以删除元素的队列一端则称为队首

importqueue

q= queue.Queue() #队列对象

q.put(1) #往队列存元素

q.put(2)

q.put('a')

q.put([1,2,3])print(q.get()) #1 取元素

print(q.get()) #2

print(q.get()) #a

2、双端队列(双端列表)

#list的缺点:list在插入元素(insert)的时候是非常慢的,因为你插入一个元素,那么此元素后面的所有元素索引都得改变,#当数据量很大的时候,那么速度就很慢了。#双端队列:可以弥补List的这个缺点#双端队列:deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。

from collections importdeque

dq= deque([1,2,3])

dq.append(4)

dq.append(5)

dq.appendleft(6)print(dq) #deque([6, 1, 2, 3, 4, 5])

print(dq.pop()) #5

print(dq.popleft()) #6

四、有序字典

python3.6之前,字典的Key是无序的(3.6之后字典默认有序,无需用此方法,但是很多公司未必都是在用3.6的版本), 在对dict做迭代时,我们无法确定Key的顺序,如果要保持Key的顺序,可以用OrderedDict。

首先说明一下普通字典的创建,可以使用面向对象的方式创建

#普通字典的创建方式

dic1 = dict({'a':1,'b':2}) #括号里面直接写字典

dic2 = dict([('c',3),('d',4)]) #括号里面写列表,列表每一个元素是二元组,每个元组是字典的键和值

print(dic1) #{'a': 1, 'b': 2}

print(dic2) #{'c': 3, 'd': 4}

有序字典的创建

from collections importOrderedDict

order_dic= OrderedDict([('a', 1), ('b', 2)])#也可以这样创建

order_dic2 = OrderedDict({'c': 3, 'd': 4})print(order_dic) #OrderedDict([('a', 1), ('b', 2)])

print(order_dic2) #OrderedDict([('c', 3), ('d', 4)])

order_dic['小明'] = '嘿嘿嘿'

print(order_dic) #OrderedDict([('a', 1), ('b', 2), ('小明', '嘿嘿嘿')])

五、其他

1、namedtuple:可命名元组

from collections importnamedtuple

time= namedtuple('My_time', ['hour', 'minute', 'second'])

t1= time(17, 50, 30)print(t1) #My_time(hour=17, minute=50, second=30)

print(t1.hour) #17

print(t1.minute) #50

print(t1.second) #30

#可命名元组非常类似一个只有属性没有方法的类,#这个类最大的特点就是一旦实例化不能修改属性的值,#可命名元组不能用索引取值了,只能用属性取值,#['hour', 'minute', 'second']是对象属性名,#My_time是类的名字,而time就相当于把一个类赋值给一个变量(变量复用地址而已,实际上还是那个类)

2、defaultdict:为字典设置默认值

from collections importdefaultdict

dic= defaultdict(list) #为字典设置默认值为空列表(defaultdict里面的参数必须是可调用的)#dic = defaultdict(1) # 报错,因为数字 1 不可调用

print(dic['a']) #[]

dic['b'].append(2)print(dic['b']) #[2]

#可与匿名函数结合使用,设置任何默认值

dic = defaultdict(lambda: 'none') #lambda返回什么值都可以

print(dic['a']) #none

print(dic) #{'a': 'none'}

dic['b'] = 2

print(dic) #{'a': 'none', 'b': 2}

#例子:有如下值集合 [11,22,33,44,55,66,77,88,99,90],将所有大于 66 的值保存至字典的第一个key中,#将小于 66 的值保存至第二个key的值中。#即: {'k1': 大于66 , 'k2': 小于66}#1、用正常的字典做

lst = [11, 22, 33, 44, 55, 66, 77, 88, 99, 90]

dic={}for num inlst:if num > 66:if 'k1' not indic:

dic['k1'] =[num]else:

dic['k1'].append(num)elif num < 66:if 'k2' not indic:

dic['k2'] =[num]else:

dic['k2'].append(num)print(dic)#2、使用字典的默认值

from collections importdefaultdict

lst= [11, 22, 33, 44, 55, 66, 77, 88, 99, 90]

dic=defaultdict(list)for num inlst:if num > 66:

dic['k1'].append(num)elif num < 66:

dic['k2'].append(num)print(dic)

3、Counter

#Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,#其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。

from collections importCounter

c= Counter('aaasasabssbba')print(c) #Counter({'a': 6, 's': 4, 'b': 3})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值