【问题标题】:Using split function in python3.5python3.5中使用split函数
【发布时间】:2023-08-15 23:14:01
【问题描述】:

尝试在数字 7 处拆分字符串,我希望将 7 包含在拆分字符串的第二部分中。

代码:

a = 'cats can jump up to 7 times their tail length'

words = a.split("7")

print(words)

输出:

['cats can jump up to ', ' times their tail length']

字符串被拆分,但第二部分不包括 7。

我想知道如何包含 7。

注意:不是Python split() without removing the delimiter 的重复项,因为分隔符必须是第二个字符串的一部分。

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    一种简单而幼稚的方法就是找到要拆分的索引并对其进行切片:

    >>> a = 'cats can jump up to 7 times their tail length'
    >>> ind = a.index('7')
    >>> a[:ind], a[ind:]
    ('cats can jump up to ', '7 times their tail length')
    

    【讨论】:

    • 不错的技巧,但如果分隔符在主字符串中重复,则只会考虑第一次出现
    • @SreeramTP 如果分隔符重复,那么这是 OP 应在问题中提及的要求。
    【解决方案2】:

    在一行中,将re.split 与字符串的其余部分一起使用,并过滤re.split 留下的最后一个空字符串:

    import re
    a = 'cats can jump up to 7 times their tail length'
    print([x for x in re.split("(7.*)",a) if x])
    

    结果:

    ['cats can jump up to ', '7 times their tail length']
    

    在拆分正则表达式中使用() 告诉re.split 不要丢弃分隔符。 (7) 正则表达式可以工作,但会创建一个像 str.partition 这样的 3 项列表,并且需要一些后期处理,所以没有单行。

    现在,如果数字未知,正则表达式(再次)是最好的方法。只需将代码更改为:

    [x for x in re.split("(\d.*)",a) if x]
    

    【讨论】:

    • 如果我有一个包含数字的字符串列表,我必须从数字中拆分每个字符串。在此先感谢:)
    • 已编辑,正则表达式再简单不过了。其他解决方案将需要更多返工!
    【解决方案3】:

    另一种方法是使用str.partition:

    a = 'cats can jump up to 7 times their tail length'
    print(a.partition('7'))
    # ('cats can jump up to ', '7', ' times their tail length')
    

    要在后半部分再次加入号码,您可以使用str.join

    x, *y = a.partition('7')
    y = ''.join(y)
    print((x, y))
    # ('cats can jump up to ', '7 times their tail length')
    

    或者手动操作:

    sep = '7'
    x = a.split(sep)
    x[1] = sep + x[1]
    print(tuple(x))
    # ('cats can jump up to ', '7 times their tail length')
    

    【讨论】:

      【解决方案4】:

      re 也可以用于全局捕获:

      >>> s = 'The 7 quick brown foxes jumped 7 times over 7 lazy dogs'
      >>> sep = '7'
      >>> 
      >>> [i for i in re.split(f'({sep}[^{sep}]*)', s) if i]
      ['The ', '7 quick brown foxes jumped ', '7 times over ', '7 lazy dogs']
      

      如果 f 字符串难以阅读,请注意它的计算结果为 (7[^7]*)
      (和listcomp一样可以使用list(filter(bool, ...)),但是比较丑)


      在 Python 3.7 及更高版本中,re.split() 允许在零宽度模式上进行拆分。这意味着可以使用前瞻正则表达式,即f'(?={sep})',而不是上面显示的组。

      奇怪的是时间:如果使用re.split()(即没有编译的模式对象),组解决方案的运行速度始终比前瞻快约 1.5 倍。但是,在编译时,前瞻优于其他:

      In [4]: r_lookahead = re.compile('f(?={sep})')
      
      In [5]: r_group = re.compile(f'({sep}[^{sep}]*)')
      
      In [6]: %timeit [i for i in r_lookahead.split(s) if i]
      2.76 µs ± 207 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
      
      In [7]: %timeit [i for i in r_group.split(s) if i]
      5.74 µs ± 65.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
      
      In [8]: %timeit [i for i in r_lookahead.split(s * 512) if i]
      137 µs ± 1.93 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
      
      In [9]: %timeit [i for i in r_group.split(s * 512) if i]
      1.88 ms ± 18.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
      

      递归解决方案也可以正常工作,尽管比在已编译的正则表达式上拆分要慢(但比直接 re.split(...) 快):

      def splitkeep(s, sep, prefix=''):
          start, delim, end = s.partition(sep)
          return [prefix + start, *(end and splitkeep(end, sep, delim))]
      
      >>> s = 'The 7 quick brown foxes jumped 7 times over 7 lazy dogs'
      >>> 
      >>> splitkeep(s, '7')
      ['The ', '7 quick brown foxes jumped ', '7 times over ', '7 lazy dogs']
      

      【讨论】:

        【解决方案5】:

        还可以使用split 和列表理解来完成所有这些操作,而无需导入任何库。但是,这会使您的代码稍微“不那么漂亮”:

        a = 'cats can jump up to 7 times their tail length'
        sep = '7'
        splitString = a.split(sep)
        splitString = list(splitString[0]) + [sep+x for x in splitString[1:]]
        

        这样,splitString 将携带价值:

        ['cats can jump up to ', '7 times their tail length']
        

        【讨论】:

          【解决方案6】:

          使用枚举, 这仅在字符串不以分隔符开头时才有效

          s = 'The quick 7 the brown foxes jumped 7 times over 7 lazy dogs'
          
          separator = '7'
          splitted = s.split(separator)
          
          res = [((separator if i > 0 else '') + item).strip() for i, item in enumerate(splitted)]
          
          print(res)
          
          ['The quick', '7 the brown foxes jumped', '7 times over', '7 lazy dogs']
          
          [Program finished]
          

          【讨论】: