Python tabstop-인식 len()및 패딩 기능
문제
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;할 수 있습 같은 결과를 얻을 훨씬 더 간단합니다.에 대한 긍정적인 i
고 n
, 를 사용:
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: