una - ¿Qué mejor manera de concatenar cuerdas en python?
python separar string por caracter (9)
Comprende "mejor" como un más rápido, elegante y legible.
Tengo dos cadenas ( b
) que pueden ser nulas o no. Y quiero concatenarlos separados por un guión solo si ambos no son nulos:
a - b
a
(si b es nulo)
b
(donde a es nulo)
¿Qué tal algo simple como:
# if I always need a string even when `a` and `b` are both null,
# I would set `output` to a default beforehand.
# Or actually, as Supr points out, simply do `a or b or ''default''`
if a and b:
output = ''%s - %s'' % (a, b)
else:
output = a or b
Edición: Muchas soluciones interesantes en este hilo. Elegí esta solución porque estaba enfatizando la legibilidad y la rapidez, al menos en términos de implementación. No es la solución más escalable o interesante, pero para este ámbito funciona, y me permite pasar al siguiente problema muy rápidamente.
Algo pitónico, legible y elegante:
strings = string1, string2
''{0}{1}{2}''.format(
# output first string if it''s not empty
strings[0] if strings[0] else '''',
# join with hyphen if both strings are not empty
''-'' if all(strings) else '''',
# output second string if it''s not empty
strings[1] if strings[1] else ''''
)
Y rápido también;)
Aquí hay una opción:
("%s - %s" if (a and b) else "%s%s") % (a,b)
EDITAR: Como señaló mgilson, este código fallaría con None
; una mejor manera (pero menos legible) sería:
"%s - %s" % (a,b) if (a and b) else (a or b)
Hay muchas respuestas aquí :)
Las dos mejores respuestas (rendimiento y código limpio en una línea) son las respuestas de @icecrime y @Hoopdady
Tanto los resultados de las respuestas como los mismos, la única diferencia es el rendimiento.
cases = [
(None, ''testB''),
('''', ''testB''),
(''testA'', ''testB''),
(''testA'', ''''),
(''testA'', None),
(None, None)
]
for case in cases: print ''-''.join(filter(bool, case))
''testB''
''testB''
''testA-testB''
''testA''
''testA''
for case in cases: print ''-''.join([x for x in case if x])
''testB''
''testB''
''testA-testB''
''testA''
''testA''
Así que vamos a hacer un punto de referencia :)
import timeit
setup = ''''''
cases = [
(None, "testB"),
("", "testB"),
("testA","testB"),
("testA", ""),
("testA", None),
(None, None)
]
''''''
print min(timeit.Timer(
"for case in cases: ''-''.join([x for x in case if x])", setup=setup
).repeat(5, 1000))
0.00171494483948
print min(timeit.Timer(
"for case in cases: ''-''.join(filter(bool, case))", setup=setup
).repeat(5, 1000))
0.00283288955688
Pero, como dijo @mgilson, usar None
lugar de bool
como la función en el filter
produce el mismo resultado y tiene un rendimiento bastante mejor:
print min(timeit.Timer(
"for case in cases: ''-''.join(filter(None, case))", setup=setup
).repeat(5, 1000))
0.00154685974121
Entonces, el mejor resultado es la respuesta dada por @icecrime con la sugerencia de @mgilson:
''-''.join(filter(None, (a,b)))
La diferencia de rendimiento es en milisegundos por 1000 iteraciones (microsegundos por iteración). Por lo tanto, estos dos métodos tienen un rendimiento bastante equitativo y, para casi cualquier proyecto, puede elegir cualquiera; En caso de que su proyecto deba tener un mejor rendimiento, considerando los microsegundos, podría seguir este punto de referencia :)
Lo haría así:
def show_together(item1=None, item2=None, seperator=''-''):
return ''%s%s%s'' % (item1,seperator,item2) if item1 and item2 else item1 or item2
>>> show_together(1,1)
''1-1''
>>> show_together(1)
1
>>> show_together()
>>> show_together(4,4,''$'')
''4$4''
Prueba esto:
def myfunc(a,b):
if not b:
return a
elif not a:
return b
else:
return a+'' - ''+b
O
def myfunc(a,b):
if a and b:
return a+'' - ''+b
else:
return a or b
Solo quería ofrecer una solución de toxotes reescrita como un format
línea usando un format
.
output = "{0} - {1}".format(a, b) if (a and b) else (a or b)
Wow, parece una pregunta candente: p Mi propuesta:
'' - ''.join(filter(bool, (a, b)))
Lo que da:
>>> '' - ''.join(filter(bool, ('''', '''')))
''''
>>> '' - ''.join(filter(bool, (''1'', '''')))
''1''
>>> '' - ''.join(filter(bool, (''1'', ''2'')))
''1 - 2''
>>> '' - ''.join(filter(bool, ('''', ''2'')))
''2''
Obviamente, None
comporta como ''''
con este código.
# Concatenates a and b with '' - '' or Coalesces them if one is None
''-''.join([x for x in (a,b) if x])
Editar
Aquí están los resultados de este algoritmo (Tenga en cuenta que Ninguno funcionará igual que ''''):
>>> ''-''.join([x for x in (''foo'',''bar'') if x])
''foo-bar''
>>> ''-''.join([x for x in (''foo'','''') if x])
''foo''
>>> ''-''.join([x for x in ('''',''bar'') if x])
''bar''
>>> ''-''.join([x for x in ('''','''') if x])
''''
* También tenga en cuenta que la evaluación de Rafael, en su publicación a continuación, solo mostró una diferencia de .0002 segundos en más de 1000 iteraciones del método de filtro, se puede razonar que una pequeña diferencia puede deberse a inconsistencias en los recursos disponibles del sistema en el momento de ejecutar el script. Ejecuté su implementación en varias iteraciones y encontré que cualquiera de los algoritmos será más rápido en un 50% de las veces, ni por un amplio margen. Por lo tanto, mostrando que son básicamente equivalentes.