문제

Python 의 len()및 패딩과 같은 기능을 문자열입니다.ljust()되지 않 tabstop-인식,즉그들은' '같은 다른 하나의 폭 문자,그리고 하지 않 라운드 렌 가장 가까운 여러 개의 tabstop.예제:

len('Bear\tnecessities\t')

17 대 24(i.e4+(8-4)+11+(8-3) )

고 내가 또한 원하는 기능 pad_with_tabs(s)

pad_with_tabs('Bear', 15) = 'Bear\t\t'

보고 단순한 구현에서는 이러한-컴팩트하고 가독성을 먼저,효율의 두 번째입니다.이것은 기본적이지만 자극 질문입니다.@gnibbler-보여줄 수 있는 순수 Pythonic 솔루션 경우에도,그것은 말 20 배 더 적은 효율적인가요?

지 확인할 수 있습 앞뒤로 변환하여 str.expandtabs(TABWIDTH),하지만 그랍니다.가져올 수학을 얻 TABWIDTH * int( math.ceil(len(s)*1.0/TABWIDTH) ) 또한 것처럼 대규모입니다.

난 아무것도 관리 보다 더 우아한 다음과 같다:

TABWIDTH = 8

def pad_with_tabs(s,maxlen):
  s_len = len(s)
  while s_len < maxlen:
    s += '\t'
    s_len += TABWIDTH - (s_len % TABWIDTH)
  return s

이후 파이썬은 문자열은 변경하지 않는 한 우리는 원숭이가 패치를 우리의 기능으로 문자열 모듈을 추가하는 방법으로,우리는 또한 할당하는 결과의 기능:

s = pad_with_tabs(s, ...)

에서 특정하게 깨끗한 접근 방식을 사용하여 목록-이해 또는 문자열입니다.가입(...)

''.join([s, '\t' * ntabs])

없이 특별한 케이스의 경우 렌(s) < 정수의 배수 TABWIDTH,또는 len(s)>=maxlen 니다.

할 수 있는 사람 잘 보여 len()및 pad_with_tabs()함수는?

도움이 되었습니까?

해결책

TABWIDTH=8
def my_len(s):
    return len(s.expandtabs(TABWIDTH))

def pad_with_tabs(s,maxlen):
    return s+"\t"*((maxlen-len(s)-1)/TABWIDTH+1)

왜 사용 expandtabs()?
잘 그것은 빠르

$ python -m timeit '"Bear\tnecessities\t".expandtabs()'
1000000 loops, best of 3: 0.602 usec per loop
$ python -m timeit 'for c in "Bear\tnecessities\t":pass'
100000 loops, best of 3: 2.32 usec per loop
$ python -m timeit '[c for c in "Bear\tnecessities\t"]'
100000 loops, best of 3: 4.17 usec per loop
$ python -m timeit 'map(None,"Bear\tnecessities\t")'
100000 loops, best of 3: 2.25 usec per loop

아무것도 반복하는 문자열이가 느리기 때문에 반복은~4 시간보다 느리 expandtabs 도 수행할 때 아무것도니다.

$ python -m timeit '"Bear\tnecessities\t".split("\t")'
1000000 loops, best of 3: 0.868 usec per loop

도 그냥 나누 탭에서 시간이 더 오래 걸립니다.당신은 아직도에 대한 반복 작업이 필요한 분할 및 패드의 각 항목을 tabstop

다른 팁

믿 gnibbler 의 최고의 대부분의 prectical 경우입니다.하지만 어쨌든,다음은 순진한(없이 회계 CR LF 등)솔루션을 계산하는 문자열의 길이를 만들지 않고도 확대 복사:

def tab_aware_len(s, tabstop=8):
    pos = -1
    extra_length = 0
    while True:
        pos = s.find('\t', pos+1)
        if pos<0:
            return len(s) + extra_length
        extra_length += tabstop - (pos+extra_length) % tabstop - 1

아마도 그것은 도움이 될 수 있 일부에 대한 거대한 문자열 또는 메모리에 매핑된 파일이 있습니다.그리고 여기에는 패딩 기능을 조금 최적화:

def pad_with_tabs(s, max_len, tabstop=8):
    length = tab_aware_len(s, tabstop)
    if length<max_len:
        s += '\t' * ((max_len-1)//tabstop + 1 - length//tabstop)
    return s

TABWIDTH * int( math.ceil(len(s)*1.0/TABWIDTH) ) 실제로 대규모 이상-kill;할 수 있습 같은 결과를 얻을 훨씬 더 간단합니다.에 대한 긍정적인 in, 를 사용:

def round_up_positive_int(i, n):
    return ((i + n - 1) // n) * n

이 절차에 어떤 언어를 사용한 후,적절한 번역이 있습니다.

다음 할 수 있습니다 next_pos = round_up_positive_int(len(s), TABWIDTH)

에 대한 약간의 증가에서는 우아하는 코드 대신

while(s_len < maxlen):

이것을 사용:

while s_len < maxlen:
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top