Was bedeuten Auslassungspunkte […] in einer Liste?

196

Ich habe in Python herumgespielt. Ich habe den folgenden Code in IDLE verwendet:

p  = [1, 2]
p[1:1] = [p]
print p

Die Ausgabe war:

[1, [...], 2]

Was ist das […]? Interessanterweise könnte ich dies jetzt als Liste von Listen von Listen bis unendlich verwenden, dh

p[1][1][1]....

Ich könnte das oben genannte schreiben, solange ich wollte und es würde immer noch funktionieren.

BEARBEITEN:

  • Wie wird es im Gedächtnis dargestellt?
  • Was nützt es? Beispiele für einige Fälle, in denen es nützlich ist, wären hilfreich.
  • Jeder Link zur offiziellen Dokumentation wäre wirklich nützlich.
Aseem Bansal
quelle
Ich suche immer noch nach Antworten auf das erste und dritte Listenelement von EDIT.
Aseem Bansal
7
Ein einfacheres Beispiel wäre p = [1]; p[0] = p.
Arshajii
6
Ich denke, dies ist ein Duplikat von Was bedeutet […] (eine Ellipse) in einer Liste in Python? , obwohl die Frage (und die Antworten) in dieser Frage besser sind.
Martin Thoma
1
Dreampie ist schlau `>>> p [1: 1] = [p] >>> p 3: [1, <Rekursion auf Liste mit id = 3074777548>, 2] >>>` liefern Sie das genaue Detail
Rahul Gautam
@ RahulGautam Hab das nicht verstanden p 3: [1, <Recursion on list with id=3074777548>, 2]. Was bist du gelaufen?
Aseem Bansal

Antworten:

112

Dies bedeutet, dass Sie eine unendliche Liste erstellt haben, die in sich selbst verschachtelt ist und nicht gedruckt werden kann. penthält pwas enthält p... und so weiter. Die [...]Notation ist eine Möglichkeit, Sie darüber zu informieren und zu informieren, dass sie nicht dargestellt werden kann! Schauen Sie sich die Antwort von @ 6502 an, um ein schönes Bild zu sehen, das zeigt, was passiert.

Nun zu den drei neuen Elementen nach Ihrer Bearbeitung:

  • Diese Antwort scheint es abzudecken
  • Ignacios Link beschreibt einige mögliche Verwendungen
  • Dies ist eher ein Thema des Datenstrukturdesigns als der Programmiersprachen, daher ist es unwahrscheinlich, dass in der offiziellen Dokumentation von Python ein Verweis gefunden wird
Óscar López
quelle
Benötigt es also unendlich viel Speicher? Ich weiß, dass das nicht möglich sein kann. Wie ist es dargestellt und wozu dient es?
Aseem Bansal
21
@Zel: Listenelemente sind Referenzen. Das zweite Element ist ein Verweis auf die Liste selbst.
Ignacio Vazquez-Abrams
2
Python identifizierte es als eine Endlosschleife von Referenzen, also entschied es sich, es kurz zu machen, es ist nicht wirklich unendlich. Und nein, es ist nicht wirklich nützlich außer einem Gedankenexperiment :)
Óscar López
2
Es gibt ... einige Verwendungsmöglichkeiten für unendlich rekursive Strukturen. Aber nicht viele.
Ignacio Vazquez-Abrams
@ IgnacioVazquez-Abrams Einige Beispiele wären nützlich.
Aseem Bansal
316

Dies ist, was Ihr Code erstellt hat

Geben Sie hier die Bildbeschreibung ein

Es ist eine Liste, in der das erste und das letzte Element auf zwei Zahlen (1 und 2) zeigen und in der das mittlere Element auf die Liste selbst zeigt.

In Common Lisp wird ein solches Objekt gedruckt, wenn das Drucken kreisförmiger Strukturen aktiviert ist

#1=#(1 #1# 2)

Dies bedeutet, dass es ein Objekt (mit 1 bezeichnet #1=) gibt, das ein Vektor mit drei Elementen ist, wobei das zweite das Objekt selbst ist (auf das mit zurück verwiesen wird #1#).

In Python erhalten Sie stattdessen nur die Informationen, mit denen die Struktur kreisförmig ist [...].

In diesem speziellen Fall ist die Beschreibung nicht mehrdeutig (sie zeigt rückwärts auf eine Liste, aber es gibt nur eine Liste, also muss es diese sein). In anderen Fällen kann es jedoch mehrdeutig sein ... zum Beispiel in

[1, [2, [...], 3]]

Die Rückwärtsreferenz könnte entweder auf die äußere oder auf die innere Liste verweisen. Diese beiden unterschiedlichen Strukturen, die auf dieselbe Weise gedruckt wurden, können mit erstellt werden

x = [1, [2, 3]]
x[1][1:1] = [x[1]]

y = [1, [2, 3]]
y[1][1:1] = [y]

print(x)
print(y)

und sie würden in Erinnerung bleiben als

Geben Sie hier die Bildbeschreibung ein

6502
quelle
Sie können den Inhalt der folgenden finden [1, [2, [...], 3]]: x[1] = [2, [...], 3]und y[1] = [2, 1, [...]], 3]. Dies bedeutet, dass x aus einer 1 besteht und dann 2s wiederholt, während y aus abwechselnden 1s und 2s besteht.
Pascalhein
2
@csharpler: Natürlich können Sie die beiden durch Analyse des Inhalts unterscheiden, sie werden jedoch mit derselben Darstellung gedruckt. Im Common Lisp-Format wären sie stattdessen #(1 #1=#(2 #1# 3))für xund #1=#(1 #(2 #1# 3))für y.
6502
5
@ BurhanKhalid: Inkscape für die erste und Gimp für die zweite (weil ich die
6502
1
@csharpler: Sie können in Python keine "unendliche Liste" erstellen, da Listen tatsächlich anpassbare Arrays sind, keine verknüpften Listen. Stattdessen könnte eine "unendliche Liste" in Common Lisp mit erstellt werden #1=(1 . #1#).
6502
1
+ Wenn Sie ein Acsii-Diagramm wie dieses zeichnen möchten, versuchen Sie es: Asiiflow
Grijesh Chauhan
23

Auf die Frage "Was nützt es?" Ist hier ein konkretes Beispiel.

Die Grafikreduzierung ist eine Bewertungsstrategie, die manchmal verwendet wird, um eine Computersprache zu interpretieren. Dies ist eine gängige Strategie für die verzögerte Bewertung, insbesondere von Funktionssprachen.

Der Ausgangspunkt besteht darin, ein Diagramm zu erstellen, das die Abfolge der "Schritte" darstellt, die das Programm ausführen wird. Abhängig von den in diesem Programm verwendeten Kontrollstrukturen kann dies zu einem zyklischen Diagramm führen (da das Programm eine Art "für immer" -Schleife enthält - oder eine Rekursion verwenden, deren "Tiefe" zum Auswertungszeitpunkt bekannt ist, jedoch nicht zum Diagramm. Erstellungszeit ) ...

Um einen solchen Graphen darzustellen, benötigen Sie unendliche "Datenstrukturen" (manchmal auch genannt) rekursive Datenstrukturen bezeichnet), wie die, die Sie bemerkt haben. Normalerweise etwas komplexer.

Wenn Sie sich für dieses Thema interessieren, finden Sie hier (unter anderem) einen Vortrag zu diesem Thema:
http://undergraduate.csse.uwa.edu.au/units/CITS3211/lectureNotes/14.pdf

Sylvain Leroux
quelle
7

Wir machen das die ganze Zeit in der objektorientierten Programmierung. Wenn zwei Objekte direkt oder indirekt aufeinander verweisen, handelt es sich um unendlich rekursive Strukturen (oder um Teile derselben unendlich rekursiven Struktur, je nachdem, wie Sie sie betrachten). Deshalb sieht man in etwas so Primitivem wie einer Liste nicht so viel - weil wir das Konzept normalerweise besser als miteinander verbundene "Objekte" beschreiben als als eine "unendliche Liste".

Sie können auch ...mit einem unendlich rekursiven Wörterbuch erhalten. Angenommen, Sie möchten ein Wörterbuch der Ecken eines Dreiecks, wobei jeder Wert ein Wörterbuch der anderen Ecken ist, die mit dieser Ecke verbunden sind. Sie könnten es so einrichten:

a = {}
b = {}
c = {}
triangle = {"a": a, "b": b, "c": c}
a["b"] = b
a["c"] = c
b["a"] = a
b["c"] = c
c["a"] = a
c["b"] = b

Wenn Sie jetzt drucken triangle(oder aoder boder cfür diese Angelegenheit), werden Sie sehen, dass es voll ist, {...}weil sich zwei beliebige Ecken aufeinander beziehen.

nmclean
quelle
Einfacheres Wörterbuch Beispiel:a = {}; a['a'] = a; print a['a']['a']['a']
user650654
Für mich zeigt anstelle von "..." "<Rekursion auf Diktat mit id = ___>"
Solomon Ucko
@SolomonUcko Sie verwenden wahrscheinlich IPython, das automatisch pprint verwendet , um Dinge zu drucken. Wenn Sie %pprinteingeben, um das hübsche Drucken auszuschalten, wird es angezeigt ....
nmclean
4

Wie ich verstanden habe, ist dies ein Beispiel für einen festen Punkt

p  = [1, 2]
p[1:1] = [p]
f = lambda x:x[1]
f(p)==p
f(f(p))==p
Hanfei Sun.
quelle
Ich habe das nicht verstehen können. Es wurde versucht, diese Befehle auszuführen, es sind jedoch Fehler aufgetreten.
Aseem Bansal
@Zel: Nun, du musst vorher OP-Code hinzufügen, damit p deklariert wird.
Inkane
1
@Zel: Nun, ich bin mir nicht sicher, wie hilfreich ich selbst bin, aber Firegun sagt, dass p (und daher p [1], dargestellt als [...]) ein Fixpunkt der Funktion f ist. IMHO, dies ist eine mögliche Antwort auf die Frage "Was ist [...]?" in diesem Fall.
Inkane
1
Ich hatte das gleiche Fehlerproblem, weil ich dieses Beispiel ausprobiert hatte, nachdem ich das einfachere p = [1]; p[0] = pBeispiel ausprobiert hatte, das f = lambda x:x[0]funktionieren muss. Es ist ein Beispiel für einen Fixpunkt, aber ich konnte noch nicht erkennen, wie nützlich es ist, dies zu wissen. Der tatsächliche Wert des Fixpunkts wird rekursiv oder iterativ von einem anderen Punkt aus erreicht. Ein Beispiel, das zeigt, wie die Listenstruktur der ursprünglichen Frage zum Erstellen des Y-Kombinators verwendet wird, wäre hilfreich, wenn dies möglich ist.
Dansalmo
1
q = lambda: qmacht ein unendlich aufrufbares Lambda
whackamadoodle3000
-2

Der Name dieses speziellen Objekts ist die Ellipse. Ich denke, dass es als Singleton-Objekt im Python-Interpreter / VM implementiert ist - so etwas wie None - eine Art Sentinel. Wie Sie gesehen haben, ist es für Python eine Möglichkeit, die Referenz einer Liste in sich selbst darzustellen.

Jim Dennis
quelle
Seltsamerweise scheint es keine Möglichkeit zu geben, ein Ellipsenobjekt direkt zu instanziieren. Der Name wird beispielsweise nicht über die Builtins-Oberfläche angezeigt. So können Sie in bestimmten Fehlern (ausgelöste Ausnahmen) Verweise auf den Begriff sehen, beispielsweise wenn Sie versuchen, ein Element mithilfe eines Auslassungszeichens als Index zu extrahieren. Aber du kannst einfach sagen: el = Ellipse () oder so etwas (das ich gefunden habe).
Jim Dennis
9
Dies hat eigentlich nichts mit dem Ellipsis-Objekt zu tun. Es ist nur die Literalzeichenfolge "[...]", die gedruckt wird, wenn beim Drucken einer Liste ein Zyklus erkannt wird. Siehe Code: hg.python.org/cpython/file/84d6c1c0665e/Objects/…
Jeremy Sharpe