Warum erfordert das Erstellen einer Liste von Tupeln mithilfe des Listenverständnisses Klammern?

8

Wie in HOWTO zur funktionalen Programmierung angegeben, müssen Klammern verwendet werden, um eine Liste von Tupeln mithilfe des Listenverständnisses zu erstellen. Dies wird insbesondere im Dokument im folgenden Zitat ausgedrückt.

Um zu vermeiden, dass die Grammatik von Python mehrdeutig wird, muss der Ausdruck , wenn er ein Tupel erstellt, von Klammern umgeben sein.

Also als Beispiele:

[x, y for x in seq1 for y in seq2]  # This is a syntex error
[(x, y) for x in seq1 for y in seq2]  # This is a correct expression of list of tuples using list comprehension

Welche Mehrdeutigkeit wird vermieden, indem die Verwendung von Klammern beim Ausdrücken einer Liste von Tupeln mithilfe des Listenverständnisses erzwungen wird?

Isaac To
quelle
1
@Georgy: Leider ist die derzeit akzeptierte Antwort auf diese Frage falsch. (Es ist das, was ich vermutet hätte, bevor ich eine Bestätigung gefunden hätte, aber es ist immer noch falsch.)
user2357112 unterstützt Monica
Siehe auch Warum benötigen Tupel in einem Listenverständnis Klammern? , auf die sich die falsche Antwort @ user2357112 bezieht.
John Kugelman

Antworten:

9

Nach vielem Ausgraben der Mailingliste habe ich eine ziemlich eindeutige Aussage gefunden, dass der Parser damit einverstanden war. Die Klammern wurden obligatorisch gemacht, um die Bedeutung klarer zu machen. Hier ist ein Zitat von Guido aus dem Jahr 2000 auf der Python-Dev-Mailingliste:

Mach dir keine Sorgen. Greg Ewing hatte kein Problem damit, dies in Pythons eigener Grammatik auszudrücken, die ungefähr so ​​eingeschränkt ist, wie Parser kommen. (Es ist LL (1), was einem reinen rekursiven Abstieg mit einem Lookahead-Token entspricht, dh ohne Rückverfolgung.)

Hier ist Gregs Grammatik:

atom: ... | '[' [testlist [list_iter]] ']' | ...
  list_iter: list_for | list_if
  list_for: 'for' exprlist 'in' testlist [list_iter]
  list_if: 'if' test [list_iter]

Beachten Sie, dass zuvor die Listensyntax lautete '[' [testlist] ']'. Lassen Sie es mich anders erklären:

Der Parser analysiert eine Reihe von durch Kommas getrennten Ausdrücken. Zuvor erwartete es ']'als einzig mögliches Token danach. Nach der Änderung 'for'ist ein weiteres mögliches Folgetoken möglich. Dies ist überhaupt kein Problem für jeden Parser, der weiß, wie man passende Klammern analysiert!

Wenn Sie es lieber nicht unterstützen möchten, [x, y for ...]weil es nicht eindeutig ist (für den menschlichen Leser, nicht für den Parser!), Können wir die Grammatik wie folgt ändern:

'[' test [',' testlist | list_iter] ']'

(Beachten Sie, dass |weniger als Verkettung gebunden ist und [...]einen optionalen Teil bedeutet.)

Siehe auch die nächste Antwort im Thread, in dem Greg Ewing läuft

>>> seq = [1,2,3,4,5]
>>> [x, x*2 for x in seq]
[(1, 2), (2, 4), (3, 6), (4, 8), (5, 10)]

auf einer frühen Version des Listenverständnis-Patches, und es funktioniert gut.

user2357112 unterstützt Monica
quelle
-1

Aus den Dokumenten :

Wie Sie sehen, werden Tupel bei der Ausgabe immer in Klammern eingeschlossen, damit verschachtelte Tupel korrekt interpretiert werden. Sie können mit oder ohne umgebende Klammern eingegeben werden, obwohl häufig ohnehin Klammern erforderlich sind (wenn das Tupel Teil eines größeren Ausdrucks ist). Es ist nicht möglich, den einzelnen Elementen eines Tupels zuzuweisen. Es ist jedoch möglich, Tupel zu erstellen, die veränderbare Objekte wie Listen enthalten.

Innerhalb einer Liste sind Verständnis-Tupel in einer Liste verschachtelt. Sie müssen also in Klammern stehen. Wenn sie jedoch nicht verschachtelt sind the_tuples = 'a','b','c', sind sie beispielsweise nicht erforderlich, da sie dann automatisch als Tupel erkannt werden.

Wasif Hasan
quelle
-2

Python enthält mehrere syntaktische Elemente mit optionalen Klammern. In diesem Fall sind dies:

  • tuple wörtlich x, y
  • Generatorausdruck y for x in seq1 for y in seq2

In eindeutigen Fällen können diese ohne zusätzliche Klammern verwendet werden:

  • b = x, y
  • sum(y for x in seq1 for y in seq2)

Die Verwendung beider im selben Ausdruck ist jedoch nicht eindeutig. Klammern sind erforderlich, um die Bedeutung zu verdeutlichen:

  • [(x, y) for x in seq1 for y in seq2]
  • [x, (y for x in seq1 for y in seq2)]

Gemäß der Python3-Grammatik werden Listenanzeigen [...]so definiert, dass sie entweder eine Ausdrucksliste ( a, b, *c, d) oder ein Verständnis ( a for a in b) enthalten.

MisterMiyagi
quelle
1
Generatorausdrücke waren zum Zeitpunkt der Einführung dieser Syntax nicht vorhanden.
user2357112 unterstützt Monica
@ user2357112supportsMonica Das ändert nichts daran, dass die Mehrdeutigkeit heute besteht.
MisterMiyagi