Estoy jugando con listas por comprensión y encontré este pequeño fragmento en otro sitio:
return ''.join([`num` for num in xrange(loop_count)])
Pasé unos minutos tratando de replicar la función (escribiendo) antes de darme cuenta de que la `num`broca la estaba rompiendo.
¿Qué hace incluir una declaración en esos caracteres? Por lo que puedo ver, es el equivalente de str (num). Pero cuando lo cronometré:
return ''.join([str(num) for num in xrange(10000000)])
Tarda 4.09s mientras que:
return ''.join([`num` for num in xrange(10000000)])
tarda 2,43 s.
Ambos dan resultados idénticos, pero uno es mucho más lento. ¿Que esta pasando aqui?
EDITAR: Curiosamente ... repr()da resultados ligeramente más lentos que `num`. 2.99 vs 2.43s. Usando Python 2.6 (aún no he probado 3.0).
python
list-comprehension
Dominic Bou-Samra
fuente
fuente

Respuestas:
Las comillas invertidas son un alias obsoleto para
repr(). No los use más, la sintaxis se eliminó en Python 3.0.Usar comillas invertidas parece ser más rápido que usar
repr(num)onum.__repr__()en la versión 2.x. Supongo que se debe a que se requiere una búsqueda adicional en el diccionario en el espacio de nombres global (pararepr) o en el espacio de nombres del objeto (para__repr__), respectivamente.El uso del
dismódulo prueba mi suposición:def f1(a): return repr(a) def f2(a): return a.__repr__() def f3(a): return `a`Desmontaje muestra:
>>> import dis >>> dis.dis(f1) 3 0 LOAD_GLOBAL 0 (repr) 3 LOAD_FAST 0 (a) 6 CALL_FUNCTION 1 9 RETURN_VALUE >>> dis.dis(f2) 6 0 LOAD_FAST 0 (a) 3 LOAD_ATTR 0 (__repr__) 6 CALL_FUNCTION 0 9 RETURN_VALUE >>> dis.dis(f3) 9 0 LOAD_FAST 0 (a) 3 UNARY_CONVERT 4 RETURN_VALUEf1implica una búsqueda global derepr,f2una búsqueda de atributos__repr__, mientras que el operador de comillas invertidas se implementa en un código de operación separado. Dado que no hay sobrecarga para la búsqueda de diccionario (LOAD_GLOBAL/LOAD_ATTR) ni para las llamadas a funciones (CALL_FUNCTION), las comillas invertidas son más rápidas.Supongo que la gente de Python decidió que tener una operación separada de bajo nivel para
repr()no vale la pena, y tenerrepr()comillas inversas y ambos viola el principiopor lo que la función se eliminó en Python 3.0.
fuente
Las comillas al revés generalmente no son útiles y desaparecieron en Python 3.
Por lo que vale, esto:
''.join(map(repr, xrange(10000000)))es un poco más rápido que la versión de comillas invertidas para mí. Pero preocuparse por esto probablemente sea una optimización prematura.
fuente
timeitproduce resultados más rápidos para''.join(map(repr, xrange(0, 1000000)))que para''.join([repr(i) for i in xrange(0, 1000000)])(incluso peor para''.join( (repr(i) for i in xrange(0, 1000000)) )). Es un poco decepcionante ;-)mapse implementa en C, usando un ciclo C, que es mucho más rápido que un ciclo Python ejecutado en la máquina virtual.mapme parece perfectamente claro y conciso, y ni siquiera conozco Python.Supongo que eso
numno define el método__str__(), por lo questr()tiene que hacer una segunda búsqueda__repr__.Las comillas invertidas buscan directamente
__repr__. Si eso es cierto, entonces usar enrepr()lugar de las comillas inversas debería darle los mismos resultados.fuente