A resposta de Jason Scheirer está correta, mas poderia ser mais útil.
Primeiro, para repetir uma sequência um número inteiro de vezes, você pode usar a multiplicação sobrecarregada:
>>> 'abc' * 7
'abcabcabcabcabcabcabc'
Portanto, para repetir uma sequência até que ela tenha pelo menos o comprimento desejado, calcule o número apropriado de repetições e coloque-o no lado direito desse operador de multiplicação:
def repeat_to_at_least_length(s, wanted):
return s * (wanted//len(s) + 1)
>>> repeat_to_at_least_length('abc', 7)
'abcabcabc'
Em seguida, você pode apará-lo no comprimento exato desejado com uma fatia da matriz:
def repeat_to_length(s, wanted):
return (s * (wanted//len(s) + 1))[:wanted]
>>> repeat_to_length('abc', 7)
'abcabca'
Como alternativa, conforme sugerido na resposta do pillmod, que provavelmente ninguém rola mais o suficiente para notar, você pode usar divmod
para calcular o número de repetições completas necessárias e o número de caracteres extras, tudo de uma vez:
def pillmod_repeat_to_length(s, wanted):
a, b = divmod(wanted, len(s))
return s * a + s[:b]
Qual é melhor? Vamos compará-lo:
>>> 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]
Então, a versão do pillmod é algo 40% mais lento, o que é muito ruim, já que pessoalmente acho que é muito mais legível. Existem várias razões possíveis para isso, começando com a compilação de cerca de 40% mais instruções de bytecode.
Nota: esses exemplos usam o //
operador new-ish para truncar a divisão inteira. Isso geralmente é chamado de recurso Python 3, mas, de acordo com o PEP 238 , foi introduzido no Python 2.2. Você só precisa usá-lo no Python 3 (ou nos módulos que o possuem from __future__ import division
), mas pode usá-lo independentemente.
//
no Python 3? Ou largar+1
e usar uma chamada explícita para uma função de teto seria suficiente. Além disso, uma observação: a sequência gerada realmente tem uma repetição extra quando se divide uniformemente; o extra é cortado pela emenda. Isso me confundiu no começo.