¿Por qué la creación de una lista de tuplas usando la comprensión de listas requiere paréntesis?

8

Como se señaló en el CÓMO de Programación Funcional , para crear una lista de tuplas usando la comprensión de la lista, se deben usar paréntesis. En particular, esto se expresa en el documento en la siguiente cita.

Para evitar introducir una ambigüedad en la gramática de Python, si la expresión está creando una tupla, debe estar entre paréntesis.

Entonces, como ejemplos:

[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

¿Qué ambigüedad se evita al forzar el uso de paréntesis al expresar una lista de tuplas usando la comprensión de la lista?

Isaac a
fuente
1
@Georgy: Desafortunadamente, la respuesta actualmente aceptada sobre esa pregunta es incorrecta. (Es lo que habría adivinado antes de encontrar la confirmación de lo contrario, pero todavía está mal.)
user2357112 apoya a Monica el
Ver también ¿Por qué las tuplas en una lista de comprensión necesitan paréntesis? , que tiene la respuesta incorrecta a la que se refiere @ user2357112.
John Kugelman

Respuestas:

9

Después de un montón de búsqueda en la lista de correo, he encontrado una declaración bastante inequívoca de que el analizador estaba de acuerdo. Los paréntesis se hicieron obligatorios para aclarar el significado. Aquí hay una cita de Guido en 2000 en la lista de correo python-dev:

No te preocupes Greg Ewing no tuvo problemas para expresar esto en la propia gramática de Python, que es tan restringida como los analizadores. (Es LL (1), que es equivalente a un descenso recursivo puro con una ficha anticipada, es decir, sin retroceso).

Aquí está la gramática de Greg:

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

Tenga en cuenta que antes, la sintaxis de la lista era '[' [testlist] ']'. Déjame explicarte en diferentes términos:

El analizador analiza una serie de expresiones separadas por comas. Anteriormente, se esperaba ']'como el único token posible después de esto. Después del cambio, 'for'es otro token de seguimiento posible. ¡Esto no es un problema en absoluto para cualquier analizador que sepa cómo analizar paréntesis coincidentes!

Si prefiere no apoyarlo [x, y for ...]porque es ambiguo (¡para el lector humano, no para el analizador!), Podemos cambiar la gramática a algo como:

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

(Tenga en cuenta que se |une menos que la concatenación y [...]significa una parte opcional).

También vea la siguiente respuesta en el hilo, donde corre Greg Ewing

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

en una versión anterior del parche de comprensión de la lista, y funciona bien.

user2357112 es compatible con Monica
fuente
-1

De los documentos :

Como puede ver, las tuplas de salida siempre están encerradas entre paréntesis, de modo que las tuplas anidadas se interpretan correctamente; pueden ingresarse con o sin paréntesis, aunque a menudo los paréntesis son necesarios de todos modos (si la tupla es parte de una expresión más grande). No es posible asignar a los elementos individuales de una tupla, sin embargo, es posible crear tuplas que contienen objetos mutables, como listas.

Dentro de una lista, las tuplas de comprensión están anidadas dentro de una lista. Por lo tanto, deben estar entre paréntesis. Pero cuando no se anidan, por ejemplo, the_tuples = 'a','b','c'no son necesarios porque se reconocen automáticamente como tuplas en ese momento.

Wasif Hasan
fuente
-2

Python tiene varios elementos sintácticos con paréntesis opcionales. En este caso, estos son:

  • tuple literal x, y
  • expresión del generador y for x in seq1 for y in seq2

En casos inequívocos, estos se pueden usar sin paréntesis adicionales:

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

Sin embargo, usar ambos en la misma expresión es ambiguo. Se requieren paréntesis para aclarar el significado:

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

Como por la gramática python3, lista de pantallas [...]se definen como que contiene o bien una lista de expresiones ( a, b, *c, d) o una comprensión ( a for a in b).

MisterMiyagi
fuente
1
Las expresiones generadoras no existían en el momento en que se introdujo esta sintaxis.
user2357112 es compatible con Monica el
@ user2357112supportsMonica Eso no cambia que la ambigüedad existe hoy.
MisterMiyagi