在Python中交换字符串中的两个字符并将生成的字符串存储在列表中

4
我希望能够将字符串中的每两个字符交换位置,并将结果存储在列表中(以便稍后检查该字符串是否存在于字典中)。
我看到了一些代码可以一次性地交换所有字符,但这不是我想要的。
例如:
var = 'abcde'

期望输出:
['bacde','acbde','abdce','abced']

如何在Python中实现此功能?

4个回答

4
您可以使用以下列表推导式来实现这一点:
>>> var = 'abcde'

#                         v To reverse the substring
>>> [var[:i]+var[i:i+2][::-1]+var[i+2:] for i in range(len(var)-1)]
['bacde', 'acbde', 'abdce', 'abced']

2
假设您期望输出列表中的最后一个条目是打字错误,并且应为'abced'以保持模式继续,那么这是一种方法(尚不确定它是否基于您的用例正确推广):
In [5]: x
Out[5]: 'abcde'

In [6]: [x[:i] + x[i+1] + x[i] + x[i+2:] for i in range(len(x)-1)]
Out[6]: ['bacde', 'acbde', 'abdce', 'abced']

2

生成器函数在处理较长字符串时不会使用过多的内存:

def swap_pairs(s):
    for i in range(len(s) - 1):
        yield s[:i] + s[i + 1] + s[i] + s[i + 2:]

>>> swap_pairs('abcde')
<generator object swap_pairs at 0x1034d0f68>
>>> list(swap_pairs('abcde'))
['bacde', 'acbde', 'abdce', 'abced']

1
这是一个使用re的方法:
x = 'abcde'
[re.sub(f'(.)(.)(?=.{{{i}}}$)', "\\2\\1", x) for i in reversed(range(len(x)-1))]
# ['bacde', 'acbde', 'abdce', 'abced']

还有一个跳过双字符的变体:

x = 'abbde'
[s for s, i in (re.subn(f'(.)(?!\\1)(.)(?=.{{{i}}}$)', "\\2\\1", x) for i in reversed(range(len(x)-1))) if i]
# ['babde', 'abdbe', 'abbed']

reversed(range(len(x)-1))?我会使用range(len(x)-1,-1,-1)代替。 - Jean-François Fabre
@Jean-FrançoisFabre... 然后很快就掉进了一个陷阱。如果我没记错的话,range(len(x)-2, -1, -1) 应该是等价的。这就是为什么我经常觉得 reversed 更易读。 - Paul Panzer
是的,我没有测试你的解决方案。但我不喜欢在range上使用reversed(代码高尔夫习惯?) - Jean-François Fabre
@Jean-FrançoisFabre,我对任何一种方法都很满意。代码高尔夫选手会不会反对反转范围?因为range对象具有__reversed__方法,并返回一个range_iterator,所以官方似乎认可了这种方法,如果手动反转范围,这应该不会比直接使用__reversed__慢多少。 - Paul Panzer
我认为他们不关心速度,而是关心代码长度。 - Jean-François Fabre

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