common-lisp
Arten von Listen
Suche…
Einfache Listen
Einfache Listen sind die einfachste Art von Listen in Common Lisp. Sie sind eine geordnete Folge von Elementen. Sie unterstützen grundlegende Operationen wie das Abrufen des ersten Elements einer Liste und des Restes einer Liste in konstanter Zeit, den Direktzugriff in linearer Zeit.
(list 1 2 3)
;=> (1 2 3)
(first (list 1 2 3))
;=> 1
(rest (list 1 2 3))
;=> (2 3)
Es gibt viele Funktionen, die auf "einfachen" Listen arbeiten, sofern sie sich nur für die Elemente der Liste interessieren. Dazu gehören find , mapcar und viele andere. (Viele dieser Funktionen funktionieren auch mit 17.1 Sequenzkonzepten für einige dieser Funktionen.
Assoziationslisten
Einfache Listen sind nützlich, um eine Folge von Elementen darzustellen, aber manchmal ist es hilfreicher, eine Art Schlüssel zum Wertemapping darzustellen. Common Lisp bietet dazu mehrere Möglichkeiten, darunter echte Hash-Tabellen (siehe 18.1 Hash Table Concepts ). In Common Lisp gibt es zwei Hauptmethoden für die Darstellung von Schlüsseln für Werte: Eigenschaftslisten und Zuordnungslisten . In diesem Beispiel werden Zuordnungslisten beschrieben.
Eine Zuordnungsliste oder Alist ist eine "Plain" -Liste, deren Elemente gepunktete Paare sind, bei denen der Wagen jedes Paares der Schlüssel ist und die CDR jedes Paares der zugehörige Wert ist. Zum Beispiel,
(defparameter *ages* (list (cons 'john 34) (cons 'mary 23) (cons 'tim 72)))
kann als eine Zuordnungsliste betrachtet werden, die Symbole, die einen persönlichen Namen angeben, mit einer Ganzzahl, die das Alter angibt, zuordnen. Einige Abruffunktionen können mit einfachen Listenfunktionen wie member implementiert werden. Um beispielsweise das Alter von John abzurufen, könnte man schreiben
(cdr (first (member 'mary *age* :key 'car)))
;=> 23
Die Member- Funktion gibt das Ende der Liste zurück, beginnend mit einer cons-Zelle, deren Auto mary ist , das heißt ((mary. 23) (tim. 72)) . Zuerst wird das erste Element dieser Liste zurückgegeben, das heißt (mary. 23) und cdr gibt die rechte Seite dieses Paares zurück, die 23 ist . Während dies eine Möglichkeit ist, auf Werte in einer Zuordnungsliste zuzugreifen, besteht der Zweck einer Konvention wie Zuordnungslisten darin, sich von der zugrunde liegenden Repräsentation (einer Liste) zu entfernen und übergeordnete Funktionen für das Arbeiten mit der Datenstruktur bereitzustellen.
Für Zuordnungslisten ist die Abruffunktion assoc , die einen Schlüssel, eine Zuordnungsliste und optionale Testschlüsselwörter (Schlüssel, Test, Test-Nicht) verwendet und das Paar für den entsprechenden Schlüssel zurückgibt:
(assoc 'tim *ages*)
;=> (tim . 72)
Da das Ergebnis immer eine cons-Zelle ist, wenn ein Artikel vorhanden ist, und wenn assoc nil zurückgibt, war der Artikel nicht in der Liste:
(assoc 'bob *ages*)
;=> nil
Zum Aktualisieren von Werten in einer Zuordnungsliste kann setf zusammen mit cdr verwendet werden . Wenn zum Beispiel Johns Geburtstag kommt und sein Alter zunimmt, könnte einer der folgenden Vorgänge ausgeführt werden:
(setf (cdr (assoc 'john *ages*) 35)
(incf (cdr (assoc 'john *ages*)))
incf funktioniert in diesem Fall, weil es auf setf basiert.
Zuordnungslisten können auch als eine Art bidirektionaler Zuordnung verwendet werden, da die Zuordnung von Schlüsseln zu Werten basierend auf dem Wert mithilfe der umgekehrten Assoc-Funktion Rassoc abgerufen wird .
In diesem Beispiel wurde die Zuordnungsliste mithilfe von list und cons explizit erstellt. Sie können Zuordnungslisten jedoch auch mithilfe von pairlis erstellen. Dabei werden eine Liste von Schlüsseln und Daten verwendet und eine darauf basierende Zuordnungsliste erstellt:
(pairlis '(john mary tim) '(23 67 82))
;=> ((john . 23) (mary . 67) (tim . 82))
Ein einzelnes Schlüssel- und Wertepaar kann mit acons zu einer Zuordnungsliste hinzugefügt werden :
(acons 'john 23 '((mary . 67) (tim . 82)))
;=> ((john . 23) (mary . 67) (tim . 82))
Die assoc- Funktion durchsucht die Liste von links nach rechts, was bedeutet, dass Werte in einer Zuordnungsliste "maskiert" werden können, ohne sie aus einer Liste zu entfernen oder die Struktur der Liste zu aktualisieren Anfang der Liste. Dafür steht die acons- Funktion zur Verfügung:
(defvar *ages* (pairlis '(john mary tim) '(34 23 72)))
(defvar *new-ages* (acons 'mary 29 *ages*))
*new-ages*
;=> ((mary . 29) (john . 34) (mary . 23) (tim . 72))
Und jetzt wird bei einer Suche nach Mary der erste Eintrag zurückgegeben:
(assoc 'mary *new-ages*)
;=> 29
Immobilienlisten
Einfache Listen sind nützlich, um eine Folge von Elementen darzustellen, aber manchmal ist es hilfreicher, eine Art Schlüssel zum Wertemapping darzustellen. Common Lisp bietet dazu mehrere Möglichkeiten, darunter echte Hash-Tabellen (siehe 18.1 Hash Table Concepts ). In Common Lisp gibt es zwei Hauptmethoden für die Darstellung von Schlüsseln für Werte: Eigenschaftslisten und Zuordnungslisten . Dieses Beispiel beschreibt Eigenschaftslisten.
Eine Eigenschaftsliste oder plist ist eine "einfache" Liste, in der abwechselnde Werte als Schlüssel und ihre zugehörigen Werte interpretiert werden. Zum Beispiel:
(defparameter *ages* (list 'john 34 'mary 23 'tim 72))
kann als eine Eigenschaftsliste betrachtet werden, die Symbole darstellt, die einen persönlichen Namen angeben, mit einer Ganzzahl, die das Alter angibt. Einige Abruffunktionen können mit einfachen Listenfunktionen wie member implementiert werden. Um beispielsweise das Alter von John abzurufen, könnte man schreiben
(second (member 'mary *age*))
;=> 23
Die Member- Funktion gibt das Ende der Liste zurück, das mit mary beginnt, d. H. (Mary 23 tim 72) , und second gibt das zweite Element dieser Liste zurück, d. H. 23 . Während dies eine Möglichkeit ist, auf Werte in einer Eigenschaftsliste zuzugreifen, besteht der Zweck einer Konvention wie Eigenschaftslisten darin, sich von der zugrunde liegenden Repräsentation (einer Liste) zu entfernen und übergeordnete Funktionen zum Arbeiten mit der Datenstruktur bereitzustellen.
Für Eigenschaftslisten lautet die Abruffunktion getf. Diese nimmt die Eigenschaftsliste, einen Schlüssel (üblicherweise als Indikator bezeichnet ) und einen optionalen Standardwert an, der zurückgegeben werden soll, falls die Eigenschaftsliste keinen Wert für den Schlüssel enthält.
(getf *ages* 'tim)
;=> 72
(getf *ages* 'bob -1)
;=> -1
Zum Aktualisieren von Werten in einer Eigenschaftsliste kann setf verwendet werden. Wenn zum Beispiel Johns Geburtstag kommt und sein Alter zunimmt, könnte einer der folgenden Vorgänge ausgeführt werden:
(setf (getf *ages* 'john) 35)
(incf (getf *ages* 'john))
incf funktioniert in diesem Fall, weil es auf setf basiert.
Verwenden Sie get-properties , um mehrere Eigenschaften in einer Eigenschaftenliste auf einmal zu suchen.
Die getf- Funktion durchsucht die Liste von links nach rechts, was bedeutet, dass Werte in einer Eigenschaftsliste "maskiert" werden können, ohne sie aus einer Liste zu entfernen oder die Struktur der Liste zu aktualisieren. Zum Beispiel mit list * :
(defvar *ages* '(john 34 mary 23 tim 72))
(defvar *new-ages* (list* 'mary 29 *ages*))
*new-ages*
;=> (mary 29 john 34 mary 23 tim 72)
Und jetzt wird bei einer Suche nach Mary der erste Eintrag zurückgegeben:
(getf *new-ages* 'mary)
;=> 29