中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python中怎么實現一個zset數據結構

發布時間:2021-08-10 14:17:18 來源:億速云 閱讀:175 作者:Leah 欄目:編程語言

本篇文章為大家展示了python中怎么實現一個zset數據結構,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

下面上代碼。

#coding=utf-8
from bisect import bisect_left,bisect_right,insort

#定義節點
class SNode:
    def __init__(self,key=None, score=float('-inf'),next=None):
        self.key   = key
        self.score = score

    def __lt__(self,other):
        return self.score < getattr(other,'score',other)

    def __gt__(self,other):#沒定義__gt__的話會導致bisect_right出問題,即使已經定義了__lt__
        return self.score > getattr(other,'score',other)

#定義數組,用bisect維護順序
class Slist(object):
    def __init__(self):
        self.key2node = {}
        self.card = 0
        self.orderlist = []

    def findpos(self, snode):
        curpos = bisect_left(self.orderlist,snode)
        while 1:
            if self.orderlist[curpos].key==snode.key:
                break
            curpos += 1
        return curpos

    def insert(self,key,score):
        if not isinstance(score,int):raise Exception('score must be integer')
        snode = self.key2node.get(key)
        if snode:
            if score == snode.score:
                return 0
            del self.orderlist[self.findpos(snode)]
            snode.score = score
        else:
            self.card += 1
            snode = SNode(key=key,score=score)
            self.key2node[key] = snode
        insort(self.orderlist, snode)
        return 1

    def delete(self,key):
        snode = self.key2node.get(key)
        if not snode:
            return 0
        self.card -= 1
        del self.orderlist[self.findpos(snode)]
        del self.key2node[key]
        del snode
        return 1

    def search(self,key):
        return self.key2node.get(key)

class SortedSet:
    def __init__(self):
        self.slist = Slist()

    def zadd(self, key, score):
        return self.slist.insert(key, score)

    def zrem(self, key):
        return self.slist.delete(key)

    def zrank(self, key):#score相同則按字典序
        snode = self.slist.key2node.get(key)
        if not snode:
            return None
        return self.slist.findpos(snode)

    def zrevrank(self, key):
        return self.zcard - 1 - self.zrank(key)

    def zscore(self, key):
        snode = self.slist.key2node.get(key)
        return getattr(snode,'score',None)

    def zcount(self, start, end):
        ol = self.slist.orderlist
        return bisect_left(ol,end+1) - bisect_right(ol,start-1)

    @property
    def zcard(self):
        return self.slist.card

    def zrange(self, start, end, withscores=False):#score相同則按字典序
        nodes = self.slist.orderlist[start: end+1]
        if not nodes:return []
        if withscores:
            return [(x.key, x.score) for x in nodes]
        else:
            return [x.key for x in nodes]

    def zrevrange(self, start, end, withscores=False):
        card = self.zcard
        if end<0:
            end = end + card
        if start<0:
            start = start + card
        nodes = self.slist.orderlist[max(card-end-1, 0): max(card-start, 0)][::-1]
        if not nodes:return []
        if withscores:
            return [(x.key, x.score) for x in nodes]
        else:
            return [x.key for x in nodes]

    def zrangebyscore(self, start, end, withscores=False):
        ol = self.slist.orderlist
        nodes = ol[bisect_left(ol, start):bisect_right(ol, end)]
        if not nodes:return []
        if withscores:
            return [(x.key, x.score) for x in nodes]
        else:
            return [x.key for x in nodes]

    def zrevrangebyscore(self, end, start, withscores=False):
        return self.zrangebyscore(start, end, withscores)[::-1]

    def zincrby(self, key):
        snode = self.slist.key2node.get(key)
        if not snode:
            return self.zadd(key, 1)
        score = snode.score
        self.zrem(key)
        return self.zadd(key, score+1)

import contextlib
import time

timeobj = {}
class timetrace:
    @contextlib.contextmanager
    def mark(self,name):
        t = time.time()
        yield
        timeobj[name] = time.time() - t

    def stat(self):
        print '---------benchmark(100000 requests)---------'
        for k,v in timeobj.iteritems():
            print '{} {}s'.format(k,v)

tt = timetrace()

if __name__ == '__main__':
    s = SortedSet()
    s.zadd('kzc',17)
    s.zadd('a',1)
    s.zadd('b',2)
    s.zadd('c',2)
    s.zadd('d',6)
    s.zadd('hello',18)
    s.zadd('world',18)
    s.zincrby('kzc')
    print 'kzc score',s.zscore('kzc')
    print 'kzc rank',s.zrank('kzc')
    print 'kzc revrank',s.zrevrank('kzc')
    print 'zcount(1,20)',s.zcount(1,20)
    print 'zrange(2,4,withscores=True)',s.zrange(2,4,withscores=True)
    print 'zrangebyscore(1,5,withscores=True)',s.zrangebyscore(1,5,withscores=True)
    print 'zrem("c")',s.zrem('c')
    print 'zrangebyscore(1,5,withscores=True)',s.zrangebyscore(1,5,withscores=True)
    print 'zcard',s.zcard
    print 's.zadd("c",7)',s.zadd('c',7)
    print 'zcard',s.zcard
    print 'zrevrange all',s.zrevrange(0,-1,withscores=True)

    #benchmark
    import random
    keys = [str(x) for x in range(0,100000)]
    values = range(0,100000)
    random.shuffle(keys)
    with tt.mark('zadd'):
        map(lambda x,y:s.zadd(x,y),keys,values)
    with tt.mark('zscore'):
        map(s.zscore,keys)
    with tt.mark('zrank'):
        map(s.zrank,keys)
    tt.stat()

結果截圖如下:

python中怎么實現一個zset數據結構

上述內容就是python中怎么實現一個zset數據結構,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宜宾市| 南汇区| 西华县| 宁德市| 当阳市| 大厂| 定远县| 绥芬河市| 苏州市| 娄烦县| 辛集市| 大厂| 突泉县| 柯坪县| 晋宁县| 陇南市| 明溪县| 银川市| 徐汇区| 普定县| 东辽县| 泰宁县| 青海省| 藁城市| 肃北| 怀柔区| 昌邑市| 呼图壁县| 莫力| 峨边| 新巴尔虎右旗| 克山县| 横峰县| 天长市| 牡丹江市| 涟水县| 清徐县| 泾阳县| 青神县| 永春县| 黄骅市|