¿Por qué es en string.join(list)
lugar de list.join(string)
?
¡Esto se debe a que join
es un método de "cadena"! Crea una cadena de cualquier iterable. Si atascamos el método en las listas, ¿qué pasa cuando tenemos iterables que no son listas?
¿Qué pasa si tienes una tupla de cuerdas? Si este fuera un list
método, ¡tendría que convertir cada iterador de cadenas como list
antes para poder unir los elementos en una sola cadena! Por ejemplo:
some_strings = ('foo', 'bar', 'baz')
Vamos a rodar nuestro propio método de unión de lista:
class OurList(list):
def join(self, s):
return s.join(self)
Y para usarlo, tenga en cuenta que primero tenemos que crear una lista de cada iterable para unir las cadenas en ese iterable, desperdiciando memoria y poder de procesamiento:
>>> l = OurList(some_strings) # step 1, create our list
>>> l.join(', ') # step 2, use our list join method!
'foo, bar, baz'
Entonces vemos que tenemos que agregar un paso adicional para usar nuestro método de lista, en lugar de solo usar el método de cadena incorporado:
>>> ' | '.join(some_strings) # a single step!
'foo | bar | baz'
Advertencia de rendimiento para generadores
El algoritmo que Python usa para crear la cadena final con str.join
realmente tiene que pasar dos veces sobre el iterable, por lo que si le proporciona una expresión generadora, primero debe materializarlo en una lista antes de que pueda crear la cadena final.
Por lo tanto, aunque pasar generadores suele ser mejor que las listas de comprensión, str.join
es una excepción:
>>> import timeit
>>> min(timeit.repeat(lambda: ''.join(str(i) for i in range(10) if i)))
3.839168446022086
>>> min(timeit.repeat(lambda: ''.join([str(i) for i in range(10) if i])))
3.339879313018173
Sin embargo, la str.join
operación sigue siendo semánticamente una operación de "cadena", por lo que aún tiene sentido tenerla en el str
objeto que en varios iterables.
-
declara que se está uniendo a una lista y convirtiendo a una cadena. Está orientada a resultados.