Python的LEN()和填充功能,如string.ljust()不接受tab感知,即,它们对待“\ T”像任何其他单宽字符,并且不圆len个到制表位的最接近的倍数。 例如:

len('Bear\tnecessities\t')

是17而不是24(即4+(8-4)+11+(8-3))

和说我也希望有一个功能pad_with_tabs(s)使得

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

寻找这些简单实现 - 第二紧凑性和可读性第一,效率。 这是一个基本的,但令人不快的问题。 @gnibbler - 您可以显示一个纯粹的Python化的解决方案,即使是说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

和自Python中的字符串是不变的,除非我们想猴补丁我们的函数为string模块将其添加为一个方法,我们还必须分配给函数的结果:

s = pad_with_tabs(s, ...)

在我特别不能让使用列表理解或的string.join(...)清洁方法

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

没有特殊壳体的情况下,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

这是在你的字符串迭代将是比较慢的,因为就在迭代〜什么,即使你什么也不做循环比expandtabs慢4倍。

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

即使只是分割选项卡上需要较长的时间。你仍然需要通过拆分和垫每个项目迭代的制表位

其他提示

我相信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) )确实是一个巨大的过杀;你可以更简单地得到同样的结果。对于正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