Как эффективно повторить строку определенной длины? Например:repeat('abc', 7) -> 'abcabca'
Вот мой текущий код:
def repeat(string, length):
cur, old = 1, string
while len(string) < length:
string += old[cur-1]
cur = (cur+1)%len(old)
return string
Есть ли лучший (более питонический) способ сделать это? Может быть, используя понимание списка?
//
в Python 3? Или+1
было бы достаточно отбросить и использовать явный вызов функции потолка. Кроме того, примечание: сгенерированная строка на самом деле имеет дополнительное повторение, когда она делится равномерно; лишнее отрезано соединением. Это смутило меня сначала.int()
делает то же самое здесь, но, да,//
может быть микроскопически быстрее, потому что он делит и пол в одной команде вместо двух.Ответ Джейсона Шайрера верен, но мог бы использовать еще немного изложения.
Прежде всего, чтобы повторить строку целое число раз, вы можете использовать перегруженное умножение:
Итак, чтобы повторять строку до тех пор, пока она не будет хотя бы той длины, которую вы хотите, вы вычисляете соответствующее количество повторений и помещаете ее в правую часть этого оператора умножения:
Затем вы можете обрезать его до нужной длины с помощью среза массива:
В качестве альтернативы, как указано в ответе pillmod, что, вероятно, никто не прокручивает достаточно далеко, чтобы заметить больше, вы можете использовать,
divmod
чтобы вычислить количество необходимых полных повторений и количество дополнительных символов, все сразу:Что лучше? Давайте оценим это:
Итак, версия pillmod работает примерно на 40% медленнее, что очень плохо, так как лично я думаю, что она гораздо более читабельна. Для этого есть несколько возможных причин, начиная с его компиляции примерно на 40% больше инструкций байт-кода.
Примечание: в этих примерах используется
//
оператор new-ish для усечения целочисленного деления. Это часто называют функцией Python 3, но, согласно PEP 238 , она была введена еще в Python 2.2. Вы должны использовать его только в Python 3 (или в модулях, которые имеютfrom __future__ import division
), но вы можете использовать его независимо.источник
Это довольно питонично:
источник
0:7
если вы хотите 7 символов, как OP.источник
источник
Возможно, не самое эффективное решение, но, конечно, короткое и простое:
Дает "foobarfoobarfo". Одна вещь в этой версии заключается в том, что если длина <len (строка), то выходная строка будет усечена. Например:
Дает "фу".
Edit: на самом деле, к моему удивлению, это быстрее, чем текущее принятое решение (функция repeat_to_length), по крайней мере, для коротких строк:
Предположительно, если нить была длинной или длина была очень высокой (то есть, если расточительность
string * length
детали была высокой), то она работала бы плохо. И на самом деле мы можем изменить вышеупомянутое, чтобы проверить это:источник
Как насчет
string * (length / len(string)) + string[0:(length % len(string))]
источник
length / len(string)
нужно заключить в скобки обертку, а вам не хватает последнего]
.//
для целочисленного деления в Python 3. В0
соединении не является обязательным. (Двоеточие обязательно, конечно.)я использую это:
источник
Не то чтобы не было достаточно ответов на этот вопрос, но есть функция повтора; просто нужно составить список и затем присоединиться к выводу:
источник
"abc", 4
можно ожидать"abca"
. Это создастabcabcabcabc
Уу рекурсия!
Не будет масштабироваться вечно, но это хорошо для небольших струн. И это красиво.
Я признаю, что только что прочитал Маленького Схемера, и мне нравится рекурсия прямо сейчас.
источник
Это один из способов сделать это с помощью понимания списка, хотя он становится все более расточительным по мере увеличения длины
rpt
строки.источник
Другой подход FP:
источник
источник