Implementieren Sie die Ranking-Verarbeitung mit Bindungen in Python mithilfe von Redis Sorted Set

Ursprung

Die Geschichte des Echtzeit-Rankings mit dem Redis Sorted Set wurde bereits zerkratzt, aber es fühlt sich wie eine schnelle Suche an, und ich konnte kein konkretes Implementierungsbeispiel in Python finden, daher vereinfache ich normalerweise die Bibliothek, die ich normalerweise intern verwende. Ich werde es vorstellen.

Source Code

Ranking-Verarbeitung

ranking.py


from datetime import timedelta
from .rankinglist import RankingList


_default_expire = int(timedelta(weeks=2).total_seconds())


class Ranking(object):
    def __init__(self, client, key, expire=_default_expire):
        """
Initialisieren Sie die Klasse.

        :param object client:Redis Client.
        :param string key:Ranking-ID.
        :param int expire:Ablaufdatum des Rankings.Zwei Wochen, wenn weggelassen.
        """
        self._r = client
        self._key = key
        self._expire = expire

    def push(self, unique_id, value):
        """
Aktualisieren Sie das Ranking.

        :param string unique_id:ID zum Rang.
        :param string value:Ranking Quellwert(Punkte etc.)
        """
        self._r.zadd(self._key, long(value), unique_id)
        self.touch()

    def get_rank(self, unique_id):
        """
Holen Sie sich das Ranking.

        :param string unique_id:ID zum Rang.
        :return:Rangfolge
        """
        value = self._r.zscore(self._key, unique_id)
        if value is None:
            return None
        return self._r.zcount(self._key, '({}'.format(int(value)), 'inf') + 1

    def get_range(self, start, end):
        """
Holen Sie sich den Rangbereich.

        :param int start:Tiefgestellte Startposition.
        :param int end:Endposition des Index. start=0 and end=Bei 0,Holen Sie sich den ersten.
        :return: ['push()Einzigartig angegeben in_id', ...]
        """
        result = self._r.zrevrange(self._key, start, end)
        self.touch()
        return result

    def get_count(self):
        """
Holen Sie sich die Anzahl der Fälle.

        :return:Nummer
        """
        return self._r.zcard(self._key)

    def touch(self):
        """
Verlängern Sie das Ablaufdatum des Rankings.
        push()Und bekomme_rank()Aber es wird ausgeführt.
        """
        self._r.expire(self._key, self._expire)

    def clean(self):
        """
Ranking löschen.
        """
        self._r.delete(self._key)

    def gen_list(self, wrapper=None):
        """
Holen Sie sich die Rangliste.

        :param function wrapper:Funktion, die das Element umschließt
        :return:RankingList-Objekt

RankingList,In gewissem Maße als Liste fungieren.
Wird bei der Übergabe an Paginator of Django usw. verwendet..
        """
        return RankingList(self, wrapper)

Ein wenig verwirrend sind get_rank () und gen_list (). gen_rank () zählt die Anzahl der Personen, die höher als die aktuelle Punktzahl sind, um ein Ranking zu erhalten, das die Bindungen berücksichtigt. Das von gen_list () zurückgegebene RankingList-Objekt wird später beschrieben.

Behandle das Ranking als Liste

rankinglist.py


class RankingList(object):
    def __init__(self, rank, wrapper=None):
        self._rank = rank
        self._wrapper = wrapper

    def __getitem__(self, k):
        if isinstance(k, slice):
            start = k.start if k.start else 0
            end = k.stop - 1 if k.stop else self.__len__() - 1
            step = k.step

            unique_ids = self._rank.get_range(start, end)
            if step:
                unique_ids = unique_ids[::step]

            return [self._wrap(unique_id) for unique_id in unique_ids]
        else:
            if self.__len__() <= k:
                raise IndexError('list index out of range')
            unique_ids = self._rank.get_range(k, k)
            return self._wrap(unique_ids[0])

    def _wrap(self, unique_id):
        return self._wrapper(unique_id) if self._wrapper else unique_id

    def __len__(self):
        return self._rank.get_count()

Delegieren Sie das Ranking an eine RankingList, die sich wie eine Python-Liste verhält. Durch Übergeben von Wapper wird außerdem ein Objekt generiert und basierend auf der aus Redis extrahierten unique_id zurückgegeben.

Wie benutzt man

>>> from redis import Redis
>>> from ranking import Ranking
>>>
>>> ranking = Ranking(Redis(), 'event1')
>>>
>>> ranking.push('p1', 200)
>>> ranking.push('p2', 100)
>>> ranking.push('p3', 300)
>>> ranking.push('p1', 1000)
>>> ranking.push('p4', 1000)
>>>
>>> l1 = ranking.gen_list() # ['p4', 'p1', 'p3', 'p2']
>>> l1[2:] # ['p3', 'p2']
>>>
>>> import Player # e.g. Django Model
>>> def wrapper(id):
        return Player.objects.get(pk=id)
>>> l2 = ranking.gen_list(wrapper) # [Player('p4'), Player('p1'), Player('p3'), Player('p2')]
>>> l2[2:] # [Player('p3'), Player('p2')]
>>>
>>> [ranking.get_rank(player_id) for player_id in l1] # [1, 1, 2, 3]

Recommended Posts

Implementieren Sie die Ranking-Verarbeitung mit Bindungen in Python mithilfe von Redis Sorted Set
Implementieren Sie Redis Mutex in Python
Verwenden des Python-Modus in der Verarbeitung
Verarbeiten Sie Bilder in Python ganz einfach mit Pillow
Sortierte Liste in Python
Dateiverarbeitung in Python
Multithread-Verarbeitung in Python
Implementieren Sie XENO mit Python
Verarbeitung in Python beenden
Bildverarbeitung mit Python
Verarbeiten Sie CSV-Daten mit Python (Zählverarbeitung mit Pandas)
Implementieren Sie sum in Python
Implementieren Sie Traceroute in Python 3
Vorsichtsmaßnahmen bei der Verwendung von Python mit AtCoder
Dinge, die Sie bei der Verwendung von CGI mit Python beachten sollten.
Morphologische Analyse mit Igo + mecab-ipadic-neologd in Python (mit Ruby-Bonus)
Bildverarbeitung mit Python (Teil 2)
100 Sprachverarbeitungsklopfen mit Python 2015
UTF8-Textverarbeitung mit Python
Schaben mit Selen in Python
"Apple-Verarbeitung" mit OpenCV3 + Python3
Betreiben Sie LibreOffice mit Python
Schaben mit Chromedriver in Python
Verwenden von Quaternion mit Python ~ numpy-quaternion ~
Debuggen mit pdb in Python
Akustische Signalverarbeitung mit Python (2)
[Python] Verwenden von OpenCV mit Python (Basic)
Umgang mit Sounds in Python
Scraping mit Selen in Python
Asynchrone Verarbeitung (Threading) in Python
Implementieren Sie Naive Bayes in Python 3.3
Implementieren Sie alte Chiffren in Python
Bildverarbeitung mit Python (Teil 1)
Scraping mit Tor in Python
Tweet mit Bild in Python
Kombiniert mit Ordnungszahl in Python
Bildverarbeitung mit Python (3)
Redis Rohrauskleidung in Python
Implementieren Sie schnelles RPC in Python
Bildverarbeitungssammlung in Python
Implementieren Sie den Dijkstra-Algorithmus in Python
Implementieren Sie den Slack Chat Bot in Python
Implementieren Sie die Umkehrumkehrverarbeitung mit BitBoard
Übersetzt mit Googletrans in Python
Verwenden von OpenCV mit Python @Mac
Senden Sie mit Python mit Google Mail
Stellen Sie den Python-Test in Jenkins ein
[Python] Bildverarbeitung mit Scicit-Image
Medianfilter mit Röntgenstrahl (Medianfilter)
Bildverarbeitung mit Python 100 Knock # 10 Medianfilter
Bei Verwendung von @property in Python wird ein Attribut nicht festgelegt
Objektextraktion im Bild durch Mustervergleich mit OpenCV mit Python
Vervollständigung von Python mit Emacs mit Company-Jedi
Zahlenerkennung in Bildern mit Python
Behandeln Sie Base91-Schlüssel mit Python + Redis.
Harmonischer Mittelwert von Python (mit SciPy)
GUI-Programmierung in Python mit Appjar
Implementieren Sie die Funktion power.prop.test von R in Python