Odpowiedź Jasona Scheirera jest prawidłowa, ale przydałaby się jeszcze bardziej ekspozycja.
Po pierwsze, aby powtórzyć ciąg liczbowy liczbę całkowitą, możesz użyć przeciążonego mnożenia:
>>> 'abc' * 7
'abcabcabcabcabcabcabc'
Tak więc, aby powtórzyć ciąg, aż będzie on co najmniej tak długi, jak chcesz, oblicz odpowiednią liczbę powtórzeń i umieść ją po prawej stronie tego operatora mnożenia:
def repeat_to_at_least_length(s, wanted):
return s * (wanted//len(s) + 1)
>>> repeat_to_at_least_length('abc', 7)
'abcabcabc'
Następnie możesz przyciąć go do odpowiedniej długości za pomocą wycinka tablicy:
def repeat_to_length(s, wanted):
return (s * (wanted//len(s) + 1))[:wanted]
>>> repeat_to_length('abc', 7)
'abcabca'
Alternatywnie, jak zasugerowano w odpowiedzi pillmod, że prawdopodobnie nikt nie przewija się wystarczająco daleko, aby zauważyć, można użyć divmod
do obliczenia liczby pełnych wymaganych powtórzeń i liczby dodatkowych znaków naraz:
def pillmod_repeat_to_length(s, wanted):
a, b = divmod(wanted, len(s))
return s * a + s[:b]
Który jest lepszy? Porównajmy to:
>>> 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]
Tak więc wersja pillmod jest o około 40% wolniejsza, co jest zbyt złe, ponieważ osobiście uważam, że jest znacznie bardziej czytelna. Istnieje kilka możliwych przyczyn, zaczynając od kompilacji do około 40% więcej instrukcji kodu bajtowego.
Uwaga: w tych przykładach zastosowano //
operator nowej isy do obcinania podziału na liczby całkowite. Jest to często nazywane funkcją Python 3, ale zgodnie z PEP 238 zostało wprowadzone od samego początku w Python 2.2. Wystarczy tylko mieć go używać w Pythonie 3 (lub w modułach, które mają from __future__ import division
), ale można go używać niezależnie.
//
w Pythonie 3? Albo+1
wystarczy upuszczenie i użycie jawnego wywołania funkcji pułapu. Również uwaga: wygenerowany ciąg ma w rzeczywistości dodatkowe powtórzenie, gdy dzieli się równomiernie; dodatkowe zostaje odcięte przez połączenie. To mnie na początku pomieszało.