Ich habe gerade mit Python angefangen und habe keine Ahnung, was Memoisierung ist und wie man es verwendet. Kann ich auch ein vereinfachtes Beispiel haben?
Antworten
Zu viele Anzeigen?Lösung, die sowohl mit Positions- als auch mit Schlüsselwortargumenten arbeitet, unabhängig von der Reihenfolge, in der die Schlüsselwortargumente übergeben wurden (mit inspect.getargspec ):
import inspect
import functools
def memoize(fn):
cache = fn.cache = {}
@functools.wraps(fn)
def memoizer(*args, **kwargs):
kwargs.update(dict(zip(inspect.getargspec(fn).args, args)))
key = tuple(kwargs.get(k, None) for k in inspect.getargspec(fn).args)
if key not in cache:
cache[key] = fn(**kwargs)
return cache[key]
return memoizer
Ähnliche Frage: Identifizierung äquivalenter varargs-Funktionsaufrufe für die Memoisierung in Python
Ich wollte nur zu den bereits gegebenen Antworten hinzufügen, dass die Python-Dekorator-Bibliothek hat einige einfache aber nützliche Implementierungen, die auch "unhashable types" memoisieren können, im Gegensatz zu functools.lru_cache
.
Wenn Geschwindigkeit eine Rolle spielt:
@functools.cache
y@functools.lru_cache(maxsize=None)
sind gleich schnell und benötigen 0,122 Sekunden (bester von 15 Durchläufen) für eine Million Schleifen auf meinem System- eine globale Cache-Variable ist wesentlich langsamer und benötigt auf meinem System 0,180 Sekunden (beste von 15 Durchläufen) für eine Million Schleifen.
- a
self.cache
Die Klassenvariable ist immer noch etwas langsamer und benötigt auf meinem System 0,214 Sekunden (beste von 15 Durchläufen) für die Schleife von einer Million Mal
Die beiden letztgenannten sind ähnlich implementiert, wie es in der derzeit meistgewählte Antwort .
Dies geschieht ohne Speichererschöpfung zu verhindern, d.h. ich habe keinen Code in der class
o global
Methoden, um die Größe des Caches zu begrenzen, ist dies wirklich die Standardimplementierung. Die lru_cache
Methode hat das kostenlos, wenn Sie das brauchen.
Eine offene Frage für mich wäre, wie man etwas testen kann, das eine functools
Dekorateur. Ist es möglich, den Cache irgendwie zu leeren? Unit-Tests scheinen am saubersten zu sein, wenn man die Klassen-Methode verwendet (wo man eine neue Klasse für jeden Test instanziieren kann) oder, in zweiter Linie, die globale Variablen-Methode (da man die yourimportedmodule.cachevariable = {}
um sie zu leeren).
- See previous answers
- Weitere Antworten anzeigen
289 Stimmen
Wenn der zweite Satz des entsprechenden Wikipedia-Artikels den Satz "Mutually-recursive descent parsing[1] in einem allgemeinen Top-Down-Parsing-Algorithmus[2][3], der Mehrdeutigkeit und linke Rekursion in polynomialer Zeit und polynomialem Raum berücksichtigt" enthält, ist es meiner Meinung nach durchaus angebracht, SO zu fragen, was hier los ist.
14 Stimmen
@Clueless: Vor diesem Satz steht: "Die Memoisierung wurde auch in anderen Zusammenhängen (und zu anderen Zwecken als zur Geschwindigkeitssteigerung) verwendet, z. B. in". Es ist also nur eine Liste von Beispielen (und muss nicht verstanden werden); es ist nicht Teil der Erklärung der Memoisierung.
0 Stimmen
Hier ist eine gute Erklärung mit angehängten Beispielen der Memoisierung und wie man sie in einen Dekorator einbaut: pycogsci.info/?p=221
1 Stimmen
@StefanGruenwald Der Link ist tot. Können Sie bitte ein Update finden?
3 Stimmen
Neuer Link zur pdf-Datei, da pycogsci.info nicht erreichbar ist: people.ucsc.edu/~abrsvn/NLTK_parsing_demos.pdf
0 Stimmen
Sie können sich meinen Blogbeitrag unter u8y7541.github.io/blog_posts/lambdas_recursion_memoizing.html ansehen.
8 Stimmen
@Clueless, Der Artikel sagt eigentlich " einfach wechselseitig rekursives Descent-Parsing[1] in einem allgemeinen Top-Down-Parsing-Algorithmus[2][3], der Mehrdeutigkeit und linke Rekursion in polynomieller Zeit und polynomialem Raum berücksichtigt". Sie haben das einfach was dieses Beispiel natürlich viel klarer macht :).
1 Stimmen
Wenn ich sehe, wie viele Leute diese Frage beantwortet haben und immer noch beantworten, glaube ich an den "BIKE SHED EFFECT". de.wikipedia.org/wiki/Gesetz_der_Trivialität
1 Stimmen
@A_P zu dem Zeitpunkt, als Sie das geschrieben haben, waren alle 13 Antworten bis auf eine 5 Jahre alt (2014) und die letzte 3 Jahre alt (2016). Ich bin mir nicht sicher, ob das als "immer noch Antworten" zählt. Die Antwort, die ich gerade gepostet habe, fügt Überlegungen zur Geschwindigkeit hinzu, die ich in anderen Antworten noch nicht gesehen habe, und führt keine neue Methode oder ähnliches ein. Es gibt sicherlich Beispiele für das von Ihnen beschriebene Phänomen, aber ich bin mir nicht sicher, ob es das hier ist.