2009-11-04 20 views
68

estoy jugando un poco con las listas por comprensión y me encontré con este pequeño fragmento en otro sitio:¿Qué significan acentos abiertos al intérprete de Python: `num`

return ''.join([`num` for num in xrange(loop_count)]) 

pasé unos minutos tratando de replicar el función (escribiendo) antes de realizar el bit `num` estaba rompiéndolo.

¿Qué significa encerrar 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)]) 

Se necesita 4.09s Considerando lo siguiente:

return ''.join([`num` for num in xrange(10000000)]) 

toma 2.43s.

Ambos dan resultados idénticos pero uno es mucho más lento. ¿Que esta pasando aqui?

EDIT: Por extraño ... repr() da resultados ligeramente más lento que `num`. 2.99s vs 2.43s. Usando Python 2.6 (aún no se ha probado 3.0).

+8

Después de leer el "otro sitio" en http://skymind.com/~ocrow/python_string/, tuve una pregunta similar y encontré esta página. Buena pregunta y buena respuesta :) – netvope

Respuesta

103

Backticks son un alias obsoleto para repr(). No los use más, la sintaxis fue eliminada en Python 3.0.

El uso de patillas traseras parece ser más rápido que usar repr(num) o num.__repr__() en la versión 2.x. Supongo que se debe a que se requiere una búsqueda de diccionario adicional en el espacio de nombres global (para repr) o en el espacio de nombres del objeto (para __repr__), respectivamente.


Con el módulo de dis prueba mi hipótesis:

def f1(a): 
    return repr(a) 

def f2(a): 
    return a.__repr__() 

def f3(a): 
    return `a` 

espectáculos Desmontaje:

>>> 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_VALUE 

f1 implica una búsqueda global para repr, f2 una búsqueda de atributos para __repr__, mientras que el acento grave el operador se implementa en un código de operación separado. Como no hay sobrecarga para búsqueda de diccionario (LOAD_GLOBAL/LOAD_ATTR) ni para llamadas a función (CALL_FUNCTION), los backticks son más rápidos.

supongo que la gente de Python decidieron que tener una operación de bajo nivel separado para repr() no vale la pena, y que tengan tanto repr() y acentos abiertos viola el principio

"No debería haber uno-- y preferiblemente solo uno: forma obvia de hacerlo "

por lo que la característica se eliminó en Python 3.0.

+0

Ver mi última edición en repr() –

+0

Quería encontrar, cómo puede reemplazar los backticks con alguna llamada a función, pero parece que no es posible, ¿o no? – Jiri

+2

Utilice repr() en lugar de barras invertidas. Backticks son sintaxis depreciada para repr() come 3.0. En realidad, prefiero la apariencia de los palos en lugar de llamar a OTRA función. –

1

Mi conjetura es que num no define el método __str__(), por lo str() tiene que hacer una segunda consulta para __repr__.

Los puntos posteriores miran directamente a __repr__. Si eso es cierto, usar repr() en lugar de los backticks debería darle los mismos resultados.

9

backtick citando generalmente no es útil y se ha ido en Python 3.

Por lo que vale la pena, esto:

''.join(map(repr, xrange(10000000))) 

es marginalmente más rápido que la versión de acento grave para mí. Pero preocuparse por esto es probablemente una optimización prematura.

+2

¿Por qué dar un paso atrás y utilizar el mapa en lugar de las comprensiones de lista/iterador? – nikow

+3

En realidad, 'timeit' produce 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) para i en xrange (0, 1000000))) '). Es un poco decepcionante ;-) – RedGlyph

+5

El resultado de Bobince no me sorprende. Como regla general, los bucles implícitos en Python son más rápidos que los explícitos, a menudo mucho más rápidos. 'map' se implementa en C, utilizando un ciclo C, que es mucho más rápido que un ciclo de Python ejecutado en la máquina virtual. –

Cuestiones relacionadas