string - totitlecase - title()
Repita cadena a cierta longitud (12)
¿Qué hay de string * (length / len(string)) + string[0:(length % len(string))]
¿Cuál es una forma eficiente de repetir una cadena de cierta longitud? Ej: repeat(''abc'', 7) -> ''abcabca''
Aquí está mi código actual:
def repeat(string, length):
cur, old = 1, string
while len(string) < length:
string += old[cur-1]
cur = (cur+1)%len(old)
return string
¿Hay alguna forma mejor (más pitonica) de hacer esto? Tal vez usando la lista de comprensión?
Esta es una forma de hacerlo utilizando una lista de comprensión, aunque es cada vez más derrochador a medida que aumenta la longitud de la cadena de rpt
.
def repeat(rpt, length):
return ''''.join([rpt for x in range(0, (len(rpt) % length))])[:length]
Esto es bastante pitónico:
newstring = ''abc''*5
print newstring[0:6]
La respuesta de Jason Scheirer es correcta, pero podría usar algo más de exposición.
Primero, para repetir una cadena un número entero de veces, puedes usar la multiplicación sobrecargada:
>>> ''abc'' * 7
''abcabcabcabcabcabcabc''
Por lo tanto, para repetir una cadena hasta que sea al menos tan larga como la longitud que desee, calcule el número apropiado de repeticiones y colóquela en el lado derecho de ese operador de multiplicación:
def repeat_to_at_least_length(s, wanted):
return s * (wanted//len(s) + 1)
>>> repeat_to_at_least_length(''abc'', 7)
''abcabcabc''
Luego, puede recortarla a la longitud exacta que desee con una porción de matriz:
def repeat_to_length(s, wanted):
return (s * (wanted//len(s) + 1))[:wanted]
>>> repeat_to_length(''abc'', 7)
''abcabca''
Alternativamente, como se sugiere en la respuesta de Pillmod que probablemente nadie se desplace lo suficiente como para notarlo, puede usar divmod
para calcular el número de repeticiones completas necesarias y el número de caracteres adicionales, todos a la vez:
def pillmod_repeat_to_length(s, wanted):
a, b = divmod(wanted, len(s))
return s * a + s[:b]
¿Cual es mejor? Hagamos un punto de referencia:
>>> import timeit
>>> timeit.repeat(''scheirer_repeat_to_length("abcdefg", 129)'', globals=globals())
[0.3964178159367293, 0.32557755894958973, 0.32851039397064596]
>>> timeit.repeat(''pillmod_repeat_to_length("abcdefg", 129)'', globals=globals())
[0.5276265419088304, 0.46511475392617285, 0.46291469305288047]
Entonces, la versión de pillmod es algo así como un 40% más lenta, lo cual es una lástima, ya que personalmente creo que es mucho más legible. Hay varias razones posibles para esto, comenzando con su compilación hasta aproximadamente 40% más de instrucciones de bytecode.
Nota: estos ejemplos usan el operador new-ish //
para truncar la división de enteros. Esto a menudo se llama una característica de Python 3, pero de acuerdo con PEP 238 , se introdujo en Python 2.2. Solo tiene que usarlo en Python 3 (o en módulos que tengan from __future__ import division
) pero puede usarlo independientemente.
No es que no haya habido suficientes respuestas a esta pregunta, pero hay una función repetitiva; solo necesita hacer una lista de y luego unirse al resultado:
from itertools import repeat
def rep(s,n):
''''.join(list(repeat(s,n))
Otro enfoque FP:
def repeat_string(string_to_repeat, repetitions):
return ''''.join([ string_to_repeat for n in range(repetitions)])
Quizás no sea la solución más eficiente, pero ciertamente breve y simple:
def repstr(string, length):
return (string * length)[0:length]
repstr("foobar", 14)
Da "foobarfoobarfo". Una cosa sobre esta versión es que si length <len (string) la cadena de salida se truncará. Por ejemplo:
repstr("foobar", 3)
Da "foo"
Editar: para mi sorpresa, esto es más rápido que la solución actualmente aceptada (la función ''repeat_to_length''), al menos en cadenas cortas:
from timeit import Timer
t1 = Timer("repstr(''foofoo'', 30)", ''from __main__ import repstr'')
t2 = Timer("repeat_to_length(''foofoo'', 30)", ''from __main__ import repeat_to_length'')
t1.timeit() # gives ~0.35 secs
t2.timeit() # gives ~0.43 secs
Presumiblemente, si la cuerda era larga, o la longitud era muy alta (es decir, si el desperdicio de la parte de string * length
de la string * length
era alto) no funcionaría bien. Y, de hecho, podemos modificar lo anterior para verificar esto:
from timeit import Timer
t1 = Timer("repstr(''foofoo'' * 10, 3000)", ''from __main__ import repstr'')
t2 = Timer("repeat_to_length(''foofoo'' * 10, 3000)", ''from __main__ import repeat_to_length'')
t1.timeit() # gives ~18.85 secs
t2.timeit() # gives ~1.13 secs
yo uso esto:
def extend_string(s, l):
return (s*l)[:l]
¡Sí, recursión!
def trunc(s,l):
if l > 0:
return s[:l] + trunc(s, l - len(s))
return ''''
No se escalará para siempre, pero está bien para cadenas más pequeñas. Y es lindo
Admito que acabo de leer el Little Schemer y me gusta la recursión en este momento.
def rep(s, m):
a, b = divmod(m, len(s))
return s * a + s[:b]
def repeat_to_length(string_to_expand, length):
return (string_to_expand * ((length/len(string_to_expand))+1))[:length]
Para python3:
def repeat_to_length(string_to_expand, length):
return (string_to_expand * (int(length/len(string_to_expand))+1))[:length]
from itertools import cycle, islice
def srepeat(string, n):
return ''''.join(islice(cycle(string), n))