2010-11-12 27 views
22

Me doy cuenta de que si tiene un iterable siempre debe usar .join(iterable) en lugar de for x in y: str += x. Pero si solo hay un número fijo de variables que aún no están en un iterable, ¿sigue siendo el .join() el camino recomendado?Python .cate o cadena de concatenación

Por ejemplo, tengo

user = 'username' 
host = 'host' 

debo hacer

ret = user + '@' + host 

o

ret = '@'.join([user, host]) 

No estoy pidiendo tanto desde el punto de vista del rendimiento, ya que ambos se ser bastante trivial. Pero he leído gente aquí, digamos que siempre use .join() y me pregunto si hay alguna razón en particular para eso o si, en general, es una buena idea usar .join().

+6

Siempre he sido parcial a ' '% s @% s' % (usuario, host)'. –

+0

+1 por una pregunta interesante, me he preguntado lo mismo. Usualmente uso el formato para ese tipo de cosas. – GWW

Respuesta

28

Si va a crear una cadena como esa, que normalmente quiere utilizar el formato de cadenas:

>>> user = 'username' 
>>> host = 'host' 
>>> '%[email protected]%s' % (user, host) 
'[email protected]' 

Python 2.6 añadido otra forma, que no se basa en la sobrecarga de operadores y tiene algunas características adicionales:

>>> '{0}@{1}'.format(user, host) 
'[email protected]' 

Como regla general, la mayoría de las personas usarán + en cadenas solo si están agregando dos cadenas allí. Para más cadenas complejas o más, utilizan el formato de cadena, como el anterior, o ensamblan elementos en una lista y los unen (especialmente si hay alguna forma de bucle implicada). La razón para usar str.join() es que agregar cadenas juntas significa crear una nueva cadena (y potencialmente la destrucción de las antiguas) para cada adición. Python a veces puede optimizar esto, pero str.join() se vuelve más claro, más obvio y significativamente más rápido.

+11

Vale la pena señalar que la notación '%' está en desuso y que el método '.format()' es * The Way Of The Future *. Documentación pertinente: http://docs.python.org/library/string.html#formatstrings – syrion

+2

Las operaciones '%' -formatting todavía no están en desuso. Se consideran * obsoletos *, pero todavía están disponibles en todas las versiones de Python, aún no se han programado para la eliminación real y no desencadenan ningún tipo de advertencia. –

+2

Como comentario adicional, me parece un poco más triste, porque el formateo de cadenas * como operador * es una de las características peculiares de Python que inicialmente me atrajo al lenguaje. – kindall

8

(estoy bastante seguro de que todas las personas que señalan en el formato de cadenas están perdiendo la cuestión en su totalidad.)

Creación de una cadena mediante la construcción de una matriz y uniéndola es solo por motivos de rendimiento. A menos que necesite ese rendimiento, o a menos que sea la forma natural de implementarlo de todos modos, no hay ningún beneficio en hacer eso en lugar de una simple concatenación de cadenas.

Decir '@'.join([user, host]) es poco intuitivo. Me hace preguntarme: ¿por qué está haciendo esto? ¿Hay alguna sutileza en esto? ¿Hay algún caso donde podría haber más de una '@'? La respuesta es no, por supuesto, pero toma más tiempo llegar a esa conclusión que si estuviera escrito de una manera natural.

No convierta su código simplemente para evitar la concatenación de cadenas; no hay nada intrínsecamente mal con eso. Unirse a matrices es solo una optimización.

+1

No estoy seguro de cómo me "perdí el punto" en mi respuesta. Además, 'array' y 'list' no son lo mismo. –

+0

@Thomas: con un par de décadas de hábito de llamar arreglos de arreglos, no siempre hago el esfuerzo de llamarlos por el nombre menos común de Python. Creo que su respuesta no entendió el punto porque su pregunta era específicamente comparar '[] .join' con la concatenación de cadenas y preguntar si se debía evitar la concatenación de cadenas incluso en casos simples; * no * preguntando por la forma ideal de formatear ese ejemplo particular y artificial. –

+3

La pregunta era acerca de "un número fijo de variables", que es una situación común en la que se utiliza el formato de cadenas - con '%' o con 'str.format' -. Mi respuesta explica por qué las personas van por 'str.join()'. En cuanto a las listas frente a las matrices, no creo que usar el nombre incorrecto sea una idea particularmente buena, considerando que Python * does * tiene matrices, y son cosas bastante diferentes. (Y por la misma razón, para asegurarme de que los lectores no se confundan, notaré que '[] .join' no existe.) –

12

Tomo la cuestión en el sentido de: "¿Está bien para hacer esto:"

ret = user + '@' + host 

..y la respuesta es sí. Eso está perfectamente bien.

Por supuesto, debe tener en cuenta el excelente formato de las cosas que puede hacer en Python, y debe tener en cuenta que para las listas largas, "unirse" es el camino a seguir, pero para una situación simple como esta, lo que tienes es exactamente correcto. Es simple y claro, y el rendimiento no será un problema.

7

Me limitaré a señalar que siempre he tendido a utilizar la concatenación en el lugar hasta que volví a leer una parte del estilo general de Python PEP PEP-8 Style Guide for Python Code.

Código
  • debe ser escrito de una manera que no perjudica a otros implementaciones de Python (PyPy, Jython, IronPython, Pyrex, Psyco, y tal). Por ejemplo, no confíe en la implementación eficiente de CPython de la concatenación de cadenas in situ para las sentencias en la forma a + = b o a = a + b. Esas declaraciones se ejecutan más lentamente en Jython. En las partes de la biblioteca sensibles a la ejecución , se debe usar en su lugar el formulario '' .join(). Este asegurará que la concatenación ocurra en tiempo lineal a través de varias implementaciones .

A juzgar por esto, he estado convirtiendo a la práctica de utilizar une de modo que pueda retener el hábito como una práctica más automático cuando la eficiencia es extra crítico.

Así que voy a poner en mi voto para:

ret = '@'.join([user, host]) 
Cuestiones relacionadas