"Comprensiones de tupla" y el operador estrella splat / desempaquetar *

Acabo de leer la pregunta¿Por qué no hay comprensión de tuplas en Python?

En elcomentarios de la respuesta aceptada, se afirma que no hay verdaderas "comprensiones de tuplas". En cambio, nuestra opción actual es usar una expresión generadora y pasar el objeto generador resultante al constructor de tuplas:

tuple(thing for thing in things)

Alternativamente, podemos crear una lista usando una comprensión de la lista y luego pasar la lista al constructor de tuplas:

tuple([thing for thing in things])

Por último y al contrario de la respuesta aceptada,una respuesta más reciente declaró que las comprensiones de tuplas son realmente una cosa (desde Python 3.5) usando la siguiente sintaxis:

*(thing for thing in things),

Para mí, parece que el segundo ejemplo también es uno en el que primero se crea un objeto generador. ¿Es esto correcto?

¿Hay alguna diferencia entre estas expresiones en términos de lo que sucede detrás de escena? En términos de rendimiento? Supongo que el primero y el tercero podrían tener problemas de latencia, mientras que el segundo podría tener problemas de memoria (como se discute en los comentarios vinculados).

Comparando el primero y el último, ¿cuál es más pitónico?

Actualizar:

Como se esperaba, la comprensión de la lista es de hecho mucho más rápida. Sin embargo, no entiendo por qué el primero es más rápido que el tercero. ¿Alguna idea?

>>> from timeit import timeit

>>> a = 'tuple(i for i in range(10000))'
>>> b = 'tuple([i for i in range(10000)])'
>>> c = '*(i for i in range(10000)),'

>>> print('A:', timeit(a, number=1000000))
>>> print('B:', timeit(b, number=1000000))
>>> print('C:', timeit(c, number=1000000))

A: 438.98362647295824
B: 271.7554752581845
C: 455.59842588083677

Respuestas a la pregunta(1)

Su respuesta a la pregunta