python之單例模式、棧、隊列和有序字典

1、單例模式

import time
import threading


class Singleton(object):
    lock = threading.RLock()  # 定義一把鎖
    __instance = None

    def __new__(cls, *args, **kwargs):
        if cls.__instance:
            return cls.__instance  # 若是以前實例化過,不必再次實例化,由於都是同一個實例

        with cls.lock:  # 避免當線程沒有返回實例前,另外一個線程也進來了,致使出現不止一個實例
            if not cls.__instance:
                cls.__instance = super().__new__(cls)
            return cls.__instance


def task(arg):
    obj = Singleton()
    print(obj)


for i in range(10):
    t = threading.Thread(target=task,args=(i,))
    t.start()


time.sleep(10)
obj = Singleton()

 

2、棧

一、自定義一個棧

# 棧是後進先出的數據結構,可是python中並無棧這種數據結構,所以咱們本身實現
class Stack(object):

    def __init__(self):
        self.MyStack = []

    def push(self, value):
        """
        向棧插入數據
        :param value:
        :return:
        """
        self.MyStack.append(value)

    def pop(self):
        """
        從棧中取走數據
        :return:
        """
        return self.MyStack.pop()

stack = Stack()
stack.push(1)
stack.push(2)
print(stack.pop())  # 2

 

二、python中的棧

後進先出(棧)
from queue import LifoQueue
lq = LifoQueue()
lq.put(1)
lq.put(2)
lq.put(3)

print(lq.get())  # 3
print(lq.get())  # 2
print(lq.get())  # 1

 

3、隊列

一、python默認的隊列

# 隊列(queue)是一種具備先進先出特徵的線性數據結構,元素的增長只能在一端進行,元素的刪除只能在另外一端進行。可以增長元素的隊列一端稱爲隊尾,能夠刪除元素的隊列一端則稱爲隊首
import queue


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

 

二、雙端隊列(雙端列表)

# list的缺點:list在插入元素(insert)的時候是很是慢的,由於你插入一個元素,那麼此元素後面的全部元素索引都得改變,
# 當數據量很大的時候,那麼速度就很慢了。
# 雙端隊列:能夠彌補List的這個缺點
# 雙端隊列:deque除了實現list的append()和pop()外,還支持appendleft()和popleft(),這樣就能夠很是高效地往頭部添加或刪除元素。
from collections import deque


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

 

4、有序字典

python3.6以前,字典的Key是無序的(3.6以後字典默認有序,無需用此方法,可是不少公司未必都是在用3.6的版本), 在對dict作迭代時,咱們沒法肯定Key的順序,若是要保持Key的順序,能夠用OrderedDict。python

首先說明一下普通字典的建立,可使用面向對象的方式建立數據結構

# 普通字典的建立方式
dic1 = dict({'a':1,'b':2})       # 括號裏面直接寫字典
dic2 = dict([('c',3),('d',4)])   # 括號裏面寫列表,列表每個元素是二元組,每一個元組是字典的鍵和值
print(dic1)  # {'a': 1, 'b': 2}
print(dic2)  # {'c': 3, 'd': 4}

 

有序字典的建立app

from collections import OrderedDict

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), ('小明', '嘿嘿嘿')])

 

5、其餘

一、namedtuple:可命名元組

from collections import namedtuple

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就至關於把一個類賦值給一個變量(變量複用地址而已,實際上仍是那個類)

 

二、defaultdict:爲字典設置默認值

from collections import defaultdict

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}
# 一、用正常的字典作
lst = [11, 22, 33, 44, 55, 66, 77, 88, 99, 90]
dic = {}

for num in lst:
    if num > 66:
        if 'k1' not in dic:
            dic['k1'] = [num]
        else:
            dic['k1'].append(num)

    elif num < 66:
        if 'k2' not in dic:
            dic['k2'] = [num]
        else:
            dic['k2'].append(num)
print(dic)

# 二、使用字典的默認值
from collections import defaultdict

lst = [11, 22, 33, 44, 55, 66, 77, 88, 99, 90]
dic = defaultdict(list)

for num in lst:
    if num > 66:
        dic['k1'].append(num)
    elif num < 66:
        dic['k2'].append(num)
print(dic)

 

三、Counter

# Counter類的目的是用來跟蹤值出現的次數。它是一個無序的容器類型,以字典的鍵值對形式存儲,
# 其中元素做爲key,其計數做爲value。計數值能夠是任意的Interger(包括0和負數)。
from collections import Counter

c = Counter('aaasasabssbba')
print(c)  # Counter({'a': 6, 's': 4, 'b': 3})
相關文章
相關標籤/搜索