Programing

문자열을 특정 길이로 반복

crosscheck 2020. 5. 17. 15:42
반응형

문자열을 특정 길이로 반복


문자열을 특정 길이로 반복하는 효율적인 방법은 무엇입니까? 예 :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) 방법이 있습니까? 아마도 목록 이해력을 사용합니까?


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]

Jason Scheirer의 대답은 정확하지만 더 많은 설명을 사용할 수 있습니다.

먼저 문자열을 정수 번 반복하려면 오버로드 된 곱셈을 사용할 수 있습니다.

>>> '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의 답변 에서 제안한 것처럼 아무도 더 이상 알아 차리지 못할 정도로 아래로 스크롤하지 않으면 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]

필필의 버전은 40 % 느리다. 개인적으로는 훨씬 더 읽기 쉽다고 생각하기 때문에 너무 나쁘다. 약 40 % 더 많은 바이트 코드 명령어로 컴파일하는 것으로 시작하는 몇 가지 이유가 있습니다.

참고 :이 예에서는 //정수 나누기를 자르기 위해 new-ish 연산자를 사용합니다 . 이것을 종종 Python 3 기능 이라고 하지만 PEP 238 에 따르면 Python 2.2에서 다시 도입되었습니다. 당신은 파이썬 3 (또는이 모듈에서 사용하는 from __future__ import division)하지만 당신은 에 관계없이 그것을 사용할 수 있습니다.


이것은 꽤 pythonic입니다.

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

어때요? string * (length / len(string)) + string[0:(length % len(string))]


아마도 가장 효율적인 솔루션은 아니지만 짧고 간단합니다.

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

repstr("foobar", 14)

"foobarfoobarfo"를 제공합니다. 이 버전에 대한 한 가지는 length <len (string)이면 출력 문자열이 잘립니다. 예를 들면 다음과 같습니다.

repstr("foobar", 3)

"foo"를 제공합니다.

편집 : 실제로 놀랍게도, 이것은 적어도 짧은 문자열에서 현재 허용되는 솔루션 ( '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

Presumably if the string was long, or length was very high (that is, if the wastefulness of the string * length part was high) then it would perform poorly. And in fact we can modify the above to verify this:

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

i use this:

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

Not that there haven't been enough answers to this question, but there is a repeat function; just need to make a list of and then join the output:

from itertools import repeat

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

Yay recursion!

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

Won't scale forever, but it's fine for smaller strings. And it's pretty.

I admit I just read the Little Schemer and I like recursion right now.


This is one way to do it using a list comprehension, though it's increasingly wasteful as the length of the rpt string increases.

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

Another FP aproach:

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

def extended_string (word, length) :

    extra_long_word = word * (length//len(word) + 1)
    required_string = extra_long_word[:length]
    return required_string

print(extended_string("abc", 7))

참고URL : https://stackoverflow.com/questions/3391076/repeat-string-to-certain-length

반응형