关于python:3个子集中字符串的反转字符

Reverse characters of string in subset of 3

假设我的字符串是:

1
x = 'abcdefghi'

我想在3的子集中反转它,这样我的输出是:

1
x = 'cbafedihg'

即第0个索引与第2个索引交换,第3个索引与第5个索引交换,依此类推。

下面是我的代码,它基于将string转换为list并交换列表中的元素:

1
2
3
4
5
6
string_list = list(x)
for i in range(len(string_list)/3):
    string_list[i*3], string_list[i*3+2] = string_list[i*3+2], string_list[i*3]

''.join(string_list)
# Output: 'cbafedihg'

我想知道什么是最有效的和最毒气的方法来实现它。

注:len(x)%3始终为0。


上述代码可以使用string slicinglist comprehension编写为:

1
2
3
# Here x[i*3:i*3+3][::-1] will reverse the substring of 3 chars
>>> ''.join([x[i*3:i*3+3][::-1] for i in range(len(x)/3)])
'cbafedihg'

根据Delgan的评论,使用step作为3,将range本身简化为:

1
2
>>> ''.join(x[i:i+3][::-1] for i in range(0, len(x), 3))
'cbafedihg'


写一个可读性和灵活性更高的函数?

1
2
3
4
5
6
7
8
9
10
11
12
13
def get_string(input_str, step=3):
    output =""
    i = 0
    for _ in list(input_str):
        if i == len(input_str):
            return output
        elif i+step-1 >= len(input_str):
            output += input[len(input_str)-1:i-1:-1]
            return output
        else:
            output += input_str[i+step-1:i:-1] + input_str[i]
            i += step
    return output

接下来是灵活的部分:

1
2
3
4
5
6
get_string("abcdefghi")
# Ouputs 'cbafedihg'
get_string("abcdefghi", 2)
# Outputs 'badcfehgi'
get_string("abcdefghi", 5)
# Outputs 'edcbaihgf'

更不用说,如果你想添加更多的逻辑或者改变逻辑,在这里更容易改变。


实现这一点的另一种选择是将字符串类型转换为list,然后使用步骤为3的列表切片简单地交换list的元素,并将字符串列表连接回:

1
2
3
4
>>> string_list = list(x)
>>> string_list[::3], string_list[2::3] = string_list[2::3], string_list[::3]
>>> ''.join(string_list)
'cbafedihg'