【问题标题】:What is the simplest way to swap each pair of adjoining chars in a string with Python?用 Python 交换字符串中每对相邻字符的最简单方法是什么?
【发布时间】:2011-06-04 01:49:07
【问题描述】:

我想交换字符串中的每一对字符。 '2143' 变为 '1234''badcfe' 变为 'abcdef'

如何在 Python 中做到这一点?

【问题讨论】:

    标签: python string


    【解决方案1】:

    这是一种方法...

    >>> s = '2134'
    >>> def swap(c, i, j):
    ...  c = list(c)
    ...  c[i], c[j] = c[j], c[i]
    ...  return ''.join(c)
    ...
    >>> swap(s, 0, 1)
    '1234'
    >>>
    

    【讨论】:

    • 你的参数中有一个's',而你的身体没有's'!在编辑中修复。
    • s = '2143' 而不是 '2134' 你使用了 undefined var c
    • 只交换第一个字符,如果你想交换所有你必须拆分并加入字符串 len(s)/2 次。
    【解决方案2】:

    您想要对数字进行排序吗?或者你在交换奇数/偶数索引数字?你的例子完全不清楚。

    排序:

    s = '2143'
    p=list(s)
    p.sort()
    s = "".join(p)
    

    s 现在是“1234”。诀窍在于 list(string) 将其分解为字符。

    【讨论】:

    • 请注意,只需执行''.join(sorted(s)) 会更简洁,并且同样清晰。
    • 对此感到抱歉。我想交换字符串中的每两个字符。
    • 我总是忘记 sorted(x) !谢谢。
    【解决方案3】:

    循环遍历字符串的长度并交换:

    def oddswap(st):
        s = list(st)
        for c in range(0,len(s),2):
            t=s[c]
            s[c]=s[c+1]
            s[c+1]=t
    
        return "".join(s)
    

    给予:

    >>> s
    'foobar'
    >>> oddswap(s)
    'ofbora'
    

    在奇数长度的字符串上失败并出现 IndexError 异常。

    【讨论】:

      【解决方案4】:

      在 Python 中交换两个项目的常用方法是:

      a, b = b, a
      

      所以在我看来,你会用扩展切片做同样的事情。但是,它有点复杂,因为字符串是不可变的。所以您必须先转换为列表,然后再转换回字符串。
      因此,我会做以下事情:

      >>> s = 'badcfe'
      >>> t = list(s)
      >>> t[::2], t[1::2] = t[1::2], t[::2]
      >>> ''.join(t)
      'abcdef'
      

      【讨论】:

      • Paulo 或 Fabian,除了抛出异常之外,对于无效输入,您希望发生什么?
      【解决方案5】:
      ''.join(s[i+1]+s[i] for i in range(0, len(s), 2)) # 10.6 usec per loop
      

      ''.join(x+y for x, y in zip(s[1::2], s[::2])) # 10.3 usec per loop
      

      或者如果字符串可以有奇数长度:

      ''.join(x+y for x, y in itertools.izip_longest(s[1::2], s[::2], fillvalue=''))
      

      请注意,这不适用于旧版本的 Python(如果我没有弄错早于 2.5 的版本)。

      基准测试在 python-2.7-8.fc14.1.x86_64 和带有s='0123456789'*4 的 Core 2 Duo 6400 CPU 上运行。

      【讨论】:

      • 对于奇数 len(s),第一个给出 IndexError: string index out of range,第二个印最后一个字符。
      • @paulo:OP 对奇数长度字符串的要求是什么?
      • @Paulo Scardine:你是对的,但问题不够具体。
      • @SilentGhost:暗示任意长度,因为不需要偶数长度
      • @paulo:OP 谈论的是“一对”字符,示例不包括奇数长度的字符串,因此暗示只考虑偶数长度的字符串。
      【解决方案6】:

      像这样:

      >>> s = "2143658709"
      >>> ''.join([s[i+1] + s[i] for i in range(0, len(s), 2)])
      '1234567890'
      
      >>> s = "badcfe"
      >>> ''.join([s[i+1] + s[i] for i in range(0, len(s), 2)])
      'abcdef'
      

      【讨论】:

        【解决方案7】:

        单线:

        >>> s = 'badcfe'
        >>> ''.join([ s[x:x+2][::-1] for x in range(0, len(s), 2) ])
        'abcdef'
        
        • s[x:x+2] 返回从 x 到 x+2 的字符串切片;奇数镜头是安全的。
        • [::-1] 在 Python 中反转字符串
        • range(0, len(s), 2) 返回 0, 2, 4, 6 ... 而 x

        【讨论】:

          【解决方案8】:
          re.sub(r'(.)(.)',r"\2\1",'abcdef1234')
          

          不过re有点慢。

          def swap(s):
              i=iter(s)
              while True:
                  a,b=next(i),next(i)
                  yield b
                  yield a
          
          ''.join(swap("abcdef1234"))
          

          【讨论】:

            【解决方案9】:

            如果性能或优雅不是问题,并且您只想要清晰并完成工作,那么只需使用这个:

            def swap(text, ch1, ch2):
                text = text.replace(ch2, '!',)
                text = text.replace(ch1, ch2)
                text = text.replace('!', ch1)
                return text
            

            这允许您交换或简单地替换字符或子字符串。 例如,在文本中交换 'ab' 'de':

            _str = "abcdefabcdefabcdef"
            print swap(_str, 'ab','de') #decabfdecabfdecabf
            

            【讨论】:

            • 这在应用上不会受到极大限制吗?
            【解决方案10】:

            没有必要列出清单。以下适用于偶数长度的字符串:

            r = ''
            for in in range(0, len(s), 2) :
              r += s[i + 1] + s[i]
            s = r
            

            【讨论】:

            • 如果字符串的长度是奇数怎么办?
            【解决方案11】:

            另一种方式:

            >>> s='123456'
            >>> ''.join([''.join(el) for el in zip(s[1::2], s[0::2])])
            '214365'
            

            【讨论】:

              【解决方案12】:
              >>> import ctypes
              >>> s = 'abcdef'
              >>> mutable = ctypes.create_string_buffer(s)
              >>> for i in range(0,len(s),2):
              >>>     mutable[i], mutable[i+1] = mutable[i+1], mutable[i]
              >>> s = mutable.value
              >>> print s
              badcfe
              

              【讨论】:

              • 如果字符串包含非 ASCII 字符会怎样?
              【解决方案13】:
              def revstr(a):
                  b=''
                  if len(a)%2==0:
                      for i in range(0,len(a),2):
                          b += a[i + 1] + a[i]
                      a=b
                  else:
                      c=a[-1]
                      for i in range(0,len(a)-1,2):
                          b += a[i + 1] + a[i]
                      b=b+a[-1]
                      a=b
                  return b
              a=raw_input('enter a string')
              n=revstr(a)
              print n
              

              【讨论】:

                【解决方案14】:
                #Works on even/odd size strings
                str = '2143657'
                newStr = ''
                for i in range(len(str)//2):
                    newStr += str[i*2+1] + str[i*2]
                if len(str)%2 != 0:
                    newStr += str[-1]
                print(newStr)
                

                【讨论】:

                • 欢迎来到 Stack Overflow!虽然这段代码 sn-p 可以解决问题,包括说明 如何为什么 这解决了问题would really help 以提高您的帖子质量。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人!请edit您的答案添加解释,并说明适用的限制和假设。
                【解决方案15】:
                #Think about how index works with string in Python,
                >>> a = "123456"
                >>> a[::-1]
                '654321'
                

                【讨论】:

                • 这不是提问者想要的 - 请查看他们的示例。
                【解决方案16】:

                更一般的答案...您可以使用这种方法对元组或字符串进行任何单对交换:

                # item can be a string or tuple and swap can be a list or tuple of two
                # indices to swap
                def swap_items_by_copy(item, swap):
                   s0 = min(swap)
                   s1 = max(swap)
                   if isinstance(item,str):
                        return item[:s0]+item[s1]+item[s0+1:s1]+item[s0]+item[s1+1:]
                   elif isinstance(item,tuple):
                        return item[:s0]+(item[s1],)+item[s0+1:s1]+(item[s0],)+item[s1+1:]
                   else:
                        raise ValueError("Type not supported")
                

                然后你可以这样调用它:

                >>> swap_items_by_copy((1,2,3,4,5,6),(1,2))
                (1, 3, 2, 4, 5, 6)
                >>> swap_items_by_copy("hello",(1,2))
                'hlelo'
                >>> 
                

                谢天谢地,对于索引引用不存在切片的情况,python 提供了空字符串或元组。

                【讨论】:

                  【解决方案17】:

                  聚会有点晚了,但实际上有一个非常简单的方法:

                  你要找的索引序列可以表示为两个序列之和:

                   0  1  2  3 ...
                  +1 -1 +1 -1 ...
                  

                  两者都很容易表达。第一个只是range(N)。在该范围内为每个i 切换的序列是i % 2。您可以通过缩放和偏移来调整切换:

                           i % 2      ->  0  1  0  1 ...
                       1 - i % 2      ->  1  0  1  0 ...
                  2 * (1 - i % 2)     ->  2  0  2  0 ...
                  2 * (1 - i % 2) - 1 -> +1 -1 +1 -1 ...
                  

                  整个表达式简化为i + 1 - 2 * (i % 2),几乎可以直接用来连接字符串:

                  result = ''.join(string[i + 1 - 2 * (i % 2)] for i in range(len(string)))
                  

                  这仅适用于偶数长度的字符串,因此您可以使用 min 检查是否有超限:

                  N = len(string)
                  result = ''.join(string[min(i + 1 - 2 * (i % 2), N - 1)] for i in range(N))
                  

                  基本上是单线,不需要超出索引范围的任何迭代器,以及一些非常简单的整数数学。

                  【讨论】:

                    【解决方案18】:

                    从字符串中交换前两个字符的最简单方法之一是

                    inputString = '2134'
                    
                    extractChar = inputString[0:2]
                    swapExtractedChar = extractChar[::-1]          """Reverse the order of string"""
                    swapFirstTwoChar = swapExtractedChar + inputString[2:]
                     
                    # swapFirstTwoChar = inputString[0:2][::-1] + inputString[2:]     """For one line code"""
                    
                    print(swapFirstTwoChar)
                    

                    【讨论】:

                      【解决方案19】:

                      虽然上述解决方案确实有效,但我们可以用“外行”的话来说,有一个非常简单的解决方案。仍在学习 python 和字符串的人可以使用其他答案,但他们并不真正了解它们的工作原理或代码的每个部分在做什么,而没有海报的完整解释而不是“这有效”。下面执行字符串中每隔一个字符的交换,对于初学者来说很容易理解它是如何工作的。

                      它只是简单地迭代字符串(任何长度)(从 0 开始并找到每个第二个字符),然后通过添加当前索引 + 1(第二个字符)然后实际创建一个新字符串(swapped_pa​​ir)索引(第一个字符),例如,索引 1 放在索引 0 处,然后索引 0 放在索引 1 处,这会通过字符串的迭代重复。

                      还添加了代码以确保字符串的长度是偶数,因为它只适用于偶数长度。

                      上面的 DrSanjay Bhakkad 帖子也是一个很好的帖子,适用于偶数或奇数字符串,并且基本上与下面的功能相同。

                      string = "abcdefghijklmnopqrstuvwxyz123"
                      
                      # use this prior to below iteration if string needs to be even but is possibly odd
                      if len(string) % 2 != 0:
                          string = string[:-1]
                      
                      # iteration to swap every second character in string
                      swapped_pair = ""
                      for i in range(0, len(string), 2):
                          swapped_pair += (string[i + 1] + string[i])
                      
                      # use this after above iteration for any even or odd length of strings
                      if len(swapped_pair) % 2 != 0:
                          swapped_adj += swapped_pair[-1]
                      
                      print(swapped_pair)
                      
                      badcfehgjilknmporqtsvuxwzy21 # output if the "needs to be even" code used
                      badcfehgjilknmporqtsvuxwzy213 # output if the "even or odd" code used
                      

                      【讨论】:

                        【解决方案20】:

                        交换位置为 l 和 r 的字符串 a 中的字符

                        def swap(a, l, r):
                            a = a[0:l] + a[r] + a[l+1:r] + a[l] + a[r+1:]
                            return a
                        

                        示例: swap("aaabcccdeee", 3, 7) 返回 "aaadcccbeee"

                        【讨论】:

                          猜你喜欢
                          • 2011-04-04
                          • 1970-01-01
                          • 2012-01-07
                          • 1970-01-01
                          • 1970-01-01
                          • 2011-05-22
                          • 2022-01-09
                          • 2014-07-01
                          相关资源
                          最近更新 更多