La réponse de Jason Scheirer est correcte mais pourrait utiliser un peu plus d'exposé.
Tout d'abord, pour répéter une chaîne un nombre entier de fois, vous pouvez utiliser une multiplication surchargée:
>>> 'abc' * 7
'abcabcabcabcabcabcabc'
Donc, pour répéter une chaîne jusqu'à ce qu'elle soit au moins aussi longue que la longueur souhaitée, vous calculez le nombre approprié de répétitions et la placez sur le côté droit de cet opérateur de multiplication:
def repeat_to_at_least_length(s, wanted):
return s * (wanted//len(s) + 1)
>>> repeat_to_at_least_length('abc', 7)
'abcabcabc'
Ensuite, vous pouvez le couper à la longueur exacte que vous souhaitez avec une tranche de tableau:
def repeat_to_length(s, wanted):
return (s * (wanted//len(s) + 1))[:wanted]
>>> repeat_to_length('abc', 7)
'abcabca'
Alternativement, comme suggéré dans la réponse de pillmod que personne ne fait probablement défiler suffisamment pour remarquer, vous pouvez utiliser divmod
pour calculer le nombre de répétitions complètes nécessaires et le nombre de caractères supplémentaires, à la fois:
def pillmod_repeat_to_length(s, wanted):
a, b = divmod(wanted, len(s))
return s * a + s[:b]
Ce qui est mieux? Essayons de le comparer:
>>> 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]
Donc, la version de pillmod est quelque chose comme 40% plus lente, ce qui est dommage, car personnellement, je pense que c'est beaucoup plus lisible. Il y a plusieurs raisons possibles à cela, à commencer par sa compilation avec environ 40% d'instructions de bytecode supplémentaires.
Remarque: ces exemples utilisent l' //
opérateur new-ish pour tronquer la division entière. Ceci est souvent appelé une fonctionnalité Python 3, mais selon PEP 238 , elle a été introduite tout au long de Python 2.2. Vous n'avez qu'à l'utiliser en Python 3 (ou dans les modules qui l'ont from __future__ import division
) mais vous pouvez l' utiliser malgré tout.
//
en Python 3? Ou laisser tomber+1
et utiliser un appel explicite à une fonction de plafond suffirait. Aussi, une remarque: la chaîne générée a en fait une répétition supplémentaire lorsqu'elle se divise uniformément; le surplus est coupé par l'épissure. Cela m'a dérouté au début.