Повторить строку до определенной длины



каков эффективный способ повторить строку до определенной длины? Например: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) способ сделать это? Может быть, используя понимание списка?

537   12  

12 ответов:

def repeat_to_length(string_to_expand, length):
   return (string_to_expand * ((length/len(string_to_expand))+1))[:length]

для python3:

def repeat_to_length(string_to_expand, length):
    return (string_to_expand * (int(length/len(string_to_expand))+1))[:length]

ответ Джейсона Шайрера правильный, но может использовать еще несколько экспозиций.

во-первых, чтобы повторить строку целое число раз, вы можете использовать перегруженное умножение:

>>> 'abc' * 7
'abcabcabcabcabcabcabc'

Итак, чтобы повторить строку, пока она не по крайней мере пока длина, которую вы хотите, вы вычисляете соответствующее количество повторов и помещаете его в правую часть этого оператора умножения:

def repeat_to_at_least_length(s, wanted):
    return s * (wanted//len(s) + 1)

>>> repeat_to_at_least_length('abc', 7)
'abcabcabc'

затем вы можете обрезать его до точной длины вы хотите с куском массива:

def repeat_to_length(s, wanted):
    return (s * (wanted//len(s) + 1))[:wanted]

>>> repeat_to_length('abc', 7)
'abcabca'

кроме того, как полагают в pillmod это!--20--> что, вероятно, никто не прокручивает вниз достаточно далеко, чтобы заметить больше, вы можете использовать divmod чтобы вычислить количество полных повторений, необходимых, и количество дополнительных символов, все сразу:

def pillmod_repeat_to_length(s, wanted):
    a, b = divmod(wanted, len(s))
    return s * a + s[:b]

что лучше? Давайте сравним его:

>>> 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]

Итак, версия pillmod-это что-то вроде 40% медленнее, что очень плохо, так как лично я думаю, что это гораздо более читабельным. Есть несколько возможных причин для этого, начиная с компиляции на 40% больше инструкций байткода.

Примечание: в этих примерах используется new-ish // оператор усечения целочисленного деления. Это часто под названием функция Python 3, но в соответствии с PEP 238, это было введено еще в Python 2.2. Ты только есть использовать его в Python 3 (или в модулях, которые from __future__ import division), но можете использовать его независимо от.

Это довольно питон:

newstring = 'abc'*5
print newstring[0:6]
def rep(s, m):
    a, b = divmod(m, len(s))
    return s * a + s[:b]
from itertools import cycle, islice
def srepeat(string, n):
   return ''.join(islice(cycle(string), n))

Я использую этот:

def extend_string(s, l):
    return (s*l)[:l]

как о string * (length / len(string)) + string[0:(length % len(string))]

возможно, не самое эффективное решение, но, конечно, коротко и просто:

def repstr(string, length):
    return (string * length)[0:length]

repstr("foobar", 14)

дает "foobarfoobarfo". Одна вещь об этой версии заключается в том, что если length

repstr("foobar", 3)

дает "фу".

Edit: на самом деле, к моему удивлению, это быстрее, чем принятое в настоящее время решение (функция 'repeat_to_length'), по крайней мере, на коротких строках:

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

предположительно, если строка была длинной, или длина была очень высокой (то есть, если расточительность string * length часть была высокой), то он будет выполнять плохо. И на самом деле мы можем изменить выше, чтобы проверить это:

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

Не то, чтобы не было достаточно ответов на этот вопрос, но есть функция повтора; просто нужно сделать список, а затем присоединиться к выходу:

from itertools import repeat

def rep(s,n):
  ''.join(list(repeat(s,n))

Ура рекурсия!

def trunc(s,l):
    if l > 0:
        return s[:l] + trunc(s, l - len(s))
    return ''

не будет масштабироваться вечно, но это нормально для небольших строк. И это очень красиво.

Я признаю, что только что прочитал маленький интриган, и мне нравится рекурсия прямо сейчас.

Это один из способов сделать это, используя список понимания, хотя это более расточительно, как длина rpt строка увеличивает.

def repeat(rpt, length):
    return ''.join([rpt for x in range(0, (len(rpt) % length))])[:length]

еще один FP aproach:

def repeat_string(string_to_repeat, repetitions):
    return ''.join([ string_to_repeat for n in range(repetitions)])

Comments

    Ничего не найдено.