【问题标题】:Split a string to even sized chunks将字符串拆分为大小均匀的块
【发布时间】:2014-02-16 13:05:10
【问题描述】:

我怎样才能得到像'aaaaaaaaaaaaaaaaaaaaaaa' 这样的字符串 并将其拆分为 4 个长度的元组,例如 (aaaa,aaaa,aaaa)

【问题讨论】:

标签: python string tuples


【解决方案1】:

使用textwrap.wrap:

>>> import textwrap
>>> s = 'aaaaaaaaaaaaaaaaaaaaaaa'
>>> textwrap.wrap(s, 4)
['aaaa', 'aaaa', 'aaaa', 'aaaa', 'aaaa', 'aaa']

【讨论】:

  • 如果字符串包含空格,这不会失败吗?
【解决方案2】:

使用列表推导,生成器表达式:

>>> s = 'aaaaaaaaaaaaaaaaaaaaaaa'
>>> [s[i:i+4] for i in range(0, len(s), 4)]
['aaaa', 'aaaa', 'aaaa', 'aaaa', 'aaaa', 'aaa']

>>> tuple(s[i:i+4] for i in range(0, len(s), 4))
('aaaa', 'aaaa', 'aaaa', 'aaaa', 'aaaa', 'aaa')

>>> s = 'a bcdefghi j'
>>> tuple(s[i:i+4] for i in range(0, len(s), 4))
('a bc', 'defg', 'hi j')

【讨论】:

    【解决方案3】:

    使用正则表达式的另一种解决方案:

    >>> s = 'aaaaaaaaaaaaaaaaaaaaaaa'
    >>> import re
    >>> re.findall('[a-z]{4}', s)
    ['aaaa', 'aaaa', 'aaaa', 'aaaa', 'aaaa']
    >>>
    

    【讨论】:

    • 正则表达式对此有点过分了。
    • 业主要求解决方案,而不是要求最优化的解决方案,所以我只是把我们也可以这样解决。没关系,我知道它不是同类中最好的。
    • 实际上,这是一个非常好的解决方案(除了正则表达式在批量使用时速度较慢)并且乍一看比zip() 解决方案更容易理解。它可以轻松更改为使用任意字符,包括换行符:re.findall('.{4}', s, re.DOTALL) - 甚至接受不完整的尾部:re.findall('.{1,4}', s, re.DOTALL)
    【解决方案4】:

    您可以使用grouper recipezip(*[iter(s)]*4)

    In [113]: s = 'aaaaaaaaaaaaaaaaaaaaaaa'
    
    In [114]: [''.join(item) for item in zip(*[iter(s)]*4)]
    Out[114]: ['aaaa', 'aaaa', 'aaaa', 'aaaa', 'aaaa']
    

    请注意,如果字符串包含空格,textwrap.wrap 可能不会将 s 拆分为长度为 4 的字符串:

    In [43]: textwrap.wrap('I am a hat', 4)
    Out[43]: ['I am', 'a', 'hat']
    

    石斑鱼配方比使用textwrap更快:

    In [115]: import textwrap
    
    In [116]: %timeit [''.join(item) for item in zip(*[iter(s)]*4)]
    100000 loops, best of 3: 2.41 µs per loop
    
    In [117]: %timeit textwrap.wrap(s, 4)
    10000 loops, best of 3: 32.5 µs per loop
    

    并且 grouper 配方可以与任何迭代器一起使用,而 textwrap 仅适用于字符串。

    【讨论】:

      【解决方案5】:
      s = 'abcdef'
      

      我们需要分成 2 的部分

      [s[pos:pos+2] for pos,i in enumerate(list(s)) if pos%2 == 0]
      

      答案:

      ['ab', 'cd', 'ef']
      

      【讨论】:

        【解决方案6】:
        s = 'abcdefghi'
        

        k - 字符串的部分数

        k = 3
        

        parts - 存储部分字符串的列表

        parts = [s[i:i+k] for i in range(0, len(s), k)]
        

        零件 --> ['abc', 'def', 'ghi']

        【讨论】:

          【解决方案7】:

          我认为这种方法更简单。但是消息长度必须用split_size分割。或者必须在消息中添加字母。示例:message = "lorem ipsum_" 那么添加的字母可以删除。

          message = "lorem ipsum"
          
          array = []
          
          temp = ""
          
          split_size = 3
          
          for i in range(1, len(message) + 1):
              temp += message[i - 1]
          
              if i % split_size == 0:
                  array.append(temp)
                  temp = ""
          
          print(array)
          

          输出: ['lor', 'em', 'ips']

          【讨论】:

            【解决方案8】:

            这是给定问题的另一种可能的解决方案:

            def split_by_length(text, width):
                width = max(1, width)
                chunk = ""
                for v in text:
                    chunk += v
                    if len(chunk) == width:
                        yield chunk
                        chunk = ""
            
                if chunk:
                    yield chunk
            
            if __name__ == '__main__':
                x = "123456789"
                for i in range(20):
                    print(i, list(split_by_length(x, i)))
            

            输出:

            0 ['1', '2', '3', '4', '5', '6', '7', '8', '9']
            1 ['1', '2', '3', '4', '5', '6', '7', '8', '9']
            2 ['12', '34', '56', '78', '9']
            3 ['123', '456', '789']
            4 ['1234', '5678', '9']
            5 ['12345', '6789']
            6 ['123456', '789']
            7 ['1234567', '89']
            8 ['12345678', '9']
            9 ['123456789']
            10 ['123456789']
            11 ['123456789']
            12 ['123456789']
            13 ['123456789']
            14 ['123456789']
            15 ['123456789']
            16 ['123456789']
            17 ['123456789']
            18 ['123456789']
            19 ['123456789']
            

            【讨论】:

              【解决方案9】:

              童言无忌

              def wrap(string, max_width):
                  i=0
                  strings = []
                  s = ""
                  for x in string:
                      i+=1
                      if i == max_width:
                          s = s + x
                          strings.append(s)
                          s = ""
                          i = 0
                      else:
                          s = s + x
                  strings.append(s)
                  return strings
              
              wrap('ABCDEFGHIJKLIMNOQRSTUVWXYZ',4)
              # output: ['ABCD', 'EFGH', 'IJKL', 'IMNO', 'QRST', 'UVWX', 'YZ']
              

              【讨论】:

                猜你喜欢
                • 2021-06-24
                • 2023-04-02
                • 1970-01-01
                • 1970-01-01
                • 2011-10-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多