如何使用Python字符串切片以步长方式反转字符串

4

我需要翻译一个关于反转交错字符串的问题,也就是说,我有一对2-pairs(即两组相邻的内容),它们不应该像这样混在一起:

>>> interleaved = "123456"

反编译

>>> print interleaved[::-1]
654321

但实际上我想要的是:
563412

这个问题是否有字符串切片操作?
3个回答

7

对于长度为偶数的字符串,可以这样做:

>>> s = "123456"
>>> it = reversed(s)
>>> ''.join(next(it) + x for x in it)
'563412'

对于长度为奇数的字符串,您需要单独在最前面添加第一个字符:
>>> s = "7123456"
>>> it = reversed(s)
>>> (s[0] if len(s)%2 else '') + ''.join(next(it) + x for x in it)
'7563412'

使用切片和 zip
>>> s = "7123456"
>>> (s[0] if len(s)%2 else '') + ''.join(x+y for x, y in zip(s[-2::-2], s[::-2]))
'7563412'

非常有创意,我喜欢你的方法。 - avenet
Ashwini,你能为我解释一下 next(it) + x for x in it 吗?我理解 next 和 for 循环表达式,但是完整的表达式对我来说有些棘手。 - Grijesh Chauhan
1
@GrijeshChauhan reversed 返回一个反向迭代器。在迭代过程中,for循环将在此迭代器上调用next,但由于我们需要下一个项目,因此在循环内部调用了一个额外的next来获取下一个项目。因此,在第一次迭代中,x将获取'6'next(x)将返回'5',依此类推... - Ashwini Chaudhary
在阅读了你的评论后,我尝试了 >>> for x in it: next(it) + x,现在一切都清楚了。谢谢! - Grijesh Chauhan
请确保reversed迭代器知道Unicode字符串,或者您实际上没有翻转Unicode字符串。这些是不同的实体,具有组合字符等需要与仅翻转所有单个字符序列不同处理的特殊情况。 - Lasse V. Karlsen

4

据我所知,最简单的方法是使用正则表达式:

import re
''.join(re.findall('..?', '123456', flags=re.S)[::-1])
  • 输入:'123456'
  • 输出:'563412'

这个方法也适用于奇数长度的字符串,而不需要为它们实现单独的逻辑。


3
你可以将多个想法带到拆分字符串中,然后反转每个部分并重新组装(连接)列表也被反转。

例如(使用satomacoto的答案,但不太易读...)

''.join([a[::-1][i:i+2][::-1] for i in range(0, len(a), 2)]) 

或者(使用F.J.的答案)
''.join(map(''.join, zip(*[iter(a)]*2))[::-1])

等等。 (a是您的字符串)。


"[iter(a)]" 中的 "[" 和 "]" 有什么必要性?你能为我解释一下 "(*[iter(a)]*2)" 吗? - Grijesh Chauhan
1
如果有人有疑问,可以从这里了解如何在Python中使用zip(*[iter(s)]*n)How does zip(*[iter(s)]*n) work in Python? - Grijesh Chauhan
我之前也指向了这个SO问答zip(),但实际上你找到的那个A更好地涵盖了这个主题。 - ShinTakezou
1
其实,我的疑惑可以从链接问题的编辑部分中得到解答。无论如何,我想感谢您让我从您的答案中学到了技巧。 - Grijesh Chauhan
虽然这个知识已经在 Stack Overflow 上存在了,但我刚刚为楼主的当前问题挖掘出来了 :) - ShinTakezou
1
是的,我是Python学习者,今天我正在尝试从当前问题和所有答案中探索好的技巧。 - Grijesh Chauhan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接