【问题标题】:How to insert a character after every 2 characters in a string如何在字符串中每2个字符后插入一个字符
【发布时间】:2011-03-16 13:45:30
【问题描述】:

有没有一种pythonic方法可以将一个元素插入到字符串中的每个第二个元素中?

我有一个字符串:'aabbccdd',我希望最终结果是 'aa-bb-cc-dd'。

我不知道该怎么做。

【问题讨论】:

    标签: python string


    【解决方案1】:
    >>> s = 'aabbccdd'
    >>> '-'.join(s[i:i+2] for i in range(0, len(s), 2))
    'aa-bb-cc-dd'
    

    【讨论】:

    • 奇数序列呢?
    • 我认为这比公认答案中的 zip voodoo 更具 Python 风格。你不需要在 python 中的 for 循环中使用 range(len(string)) 这一事实,并不意味着你必须去发明一些疯狂的东西来避免它。
    • @hamish:它保留最后一个字符并在其前面插入一个连字符。这不是一种理想的行为吗?
    【解决方案2】:

    假设字符串的长度总是偶数,

    >>> s = '12345678'
    >>> t = iter(s)
    >>> '-'.join(a+b for a,b in zip(t, t))
    '12-34-56-78'
    

    t 也可以用

    来消除
    >>> '-'.join(a+b for a,b in zip(s[::2], s[1::2]))
    '12-34-56-78'
    

    算法是将字符串分组,然后用- 字符将它们连接起来。

    代码是这样写的。首先,它分为奇数位和偶数位。

    >>> s[::2], s[1::2]
    ('1357', '2468')
    

    然后the zip function 用于将它们组合成一个可迭代的元组。

    >>> list( zip(s[::2], s[1::2]) )
    [('1', '2'), ('3', '4'), ('5', '6'), ('7', '8')]
    

    但元组不是我们想要的。这应该是一个字符串列表。这就是列表理解的目的

    >>> [a+b for a,b in zip(s[::2], s[1::2])]
    ['12', '34', '56', '78']
    

    最后我们使用str.join()来组合列表。

    >>> '-'.join(a+b for a,b in zip(s[::2], s[1::2]))
    '12-34-56-78'
    

    第一段代码也是同样的思路,但是如果字符串长的话,占用的内存会更少。

    【讨论】:

    • 你能解释一下zip部分吗?这是在做什么?
    • @Ham:最后一个字符会消失。
    【解决方案3】:

    如果你想在字符串长度为奇数的情况下保留最后一个字符,那么你可以修改 KennyTM 的答案以使用itertools.izip_longest

    >>> s = "aabbccd"
    >>> from itertools import izip_longest
    >>> '-'.join(a+b for a,b in izip_longest(s[::2], s[1::2], fillvalue=""))
    'aa-bb-cc-d'
    

    >>> t = iter(s)
    >>> '-'.join(a+b  for a,b in izip_longest(t, t, fillvalue=""))
    'aa-bb-cc-d'
    

    【讨论】:

      【解决方案4】:

      这是一种列表理解方式,其条件值取决于枚举模数,最后一个奇数字符将单独在组中:

      for s  in ['aabbccdd','aabbccdde']:
          print(''.join([ char if not ind or ind % 2 else '-' + char
                          for ind,char in enumerate(s)
                          ]
                        )
                )
      """ Output:
      aa-bb-cc-dd
      aa-bb-cc-dd-e
      """
      

      【讨论】:

        【解决方案5】:

        我倾向于依赖正则表达式,因为它看起来不那么冗长,并且通常比所有替代方法都快。除了不得不面对有关正则表达式的传统观念之外,我不确定是否有缺点。

        >>> s = 'aabbccdd'
        >>> '-'.join(re.findall('..', s))
        'aa-bb-cc-dd'
        

        这个版本对实际配对很严格:

        >>> t = s + 'e'
        >>> '-'.join(re.findall('..', t)) 
        'aa-bb-cc-dd'
        

        ...所以通过调整你可以容忍奇数长度的字符串:

        >>> '-'.join(re.findall('..?', t))
        'aa-bb-cc-dd-e'
        

        通常你会不止一次这样做,所以也许可以提前创建一个快捷方式来抢占先机:

        PAIRS = re.compile('..').findall
        
        out = '-'.join(PAIRS(in))
        

        或者我会在实际代码中使用什么:

        def rejoined(src, sep='-', _split=re.compile('..').findall):
            return sep.join(_split(src))
        
        >>> rejoined('aabbccdd', sep=':')
        'aa:bb:cc:dd'
        

        我不时使用类似的东西从 6 字节二进制输入创建 MAC 地址表示:

        >>> addr = b'\xdc\xf7\x09\x11\xa0\x49'
        >>> rejoined(addr[::-1].hex(), sep=':')
        '49:a0:11:09:f7:dc'
        

        【讨论】:

          【解决方案6】:

          这种单线可以解决问题。如果您的字符串包含奇数个字符,它将删除最后一个字符。

          "-".join([''.join(item) for item in zip(mystring1[::2],mystring1[1::2])])
          

          【讨论】:

            【解决方案7】:

            作为PEP8 states:

            对于a += ba = a + b 形式的语句,不要依赖CPython 对就地字符串连接的高效实现。即使在 CPython 中,这种优化也很脆弱(它只适用于某些类型),并且在实现中根本不存在。

            一种避免这种连接并允许您加入除字符串以外的可迭代对象的 Pythonic 方法可能是:

            ':'.join(f'{s[i:i+2]}' for i in range(0, len(s), 2))
            

            另一种更类似于功能的方式可能是:

            ':'.join(map('{}{}'.format, *(s[::2], s[1::2]))) 
            

            第二种方法有一个特殊的功能(或错误),即只连接成对的字母。所以:

            >>> s = 'abcdefghij'
            'ab:cd:ef:gh:ij'
            

            和:

            >>> s = 'abcdefghi'
            'ab:cd:ef:gh'
            

            【讨论】:

              猜你喜欢
              • 2017-08-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-03-13
              • 1970-01-01
              • 1970-01-01
              • 2012-05-19
              相关资源
              最近更新 更多