在字符串中一次更改一个字符,不要更改字符串?

时间:2015-01-17 14:47:37

标签: python

我有一个字符串:

'ABCDEFGH'

我想循环遍历字符串,并逐个用4个字符(1,2,3,4)中的一个替换每个字符:

'ABCDEFGH'
'1BCDEFGH'
'A1CDEFGH'
'AB1DEFGH'

'2BCDEFGH'
'A2CDEFGH'
'AB2DEFGH'

等等。但是每当我尝试时,我最终都会改变原始字符串,我的输出最终会成为1s的字符串!

'1111111'

以下示例代码:

letters = 'ABCDEFGH'

s = list(letters)
y = 0 
while y < len(s): 
   s[y] = '1'
   y = y + 1

3 个答案:

答案 0 :(得分:3)

不是更改在迭代之间重复使用的列表,而是每次都生成一个新列表并替换一个字符:

for i in range(len(letters)):
    s = list(letters)
    s[i] = '1'
    print(''.join(s))

您可以将其与嵌套循环结合使用:

for digit in '1234':
    for i in range(len(letters)):
        s = list(letters)
        s[i] = digit
        print(''.join(s))

本质上,您正在创建'1234'的产品和range(len(letters))的位置,因此您可以使用itertools.product()来构建一个循环:

from itertools import product

for digit, pos in product('1234', range(len(letters))):
    s = list(letters)
    s[pos] = digit
    print(''.join(s))

使用一点enumerate()技巧,你可以将它作为单行生成器表达式来生成所有组合:

from itertools import product

all_combos = (
    ''.join([digit if i == pos else c for i, c in enumerate(letters)])
    for digit, pos in product('1234', range(len(letters))))

通过迭代letters,在数字位置pos上交换一个字符,即时构建新列表。

演示:

>>> from itertools import product
>>> letters = 'ABCDEFGH'
>>> all_combos = (
...     ''.join([digit if i == pos else c for i, c in enumerate(letters)])
...     for digit, pos in product('1234', range(len(letters))))
>>> 
>>> next(all_combos)
'1BCDEFGH'
>>> next(all_combos)
'A1CDEFGH'
>>> next(all_combos)
'AB1DEFGH'
>>> next(all_combos)
'ABC1EFGH'
>>> from itertools import islice
>>> print(list(islice(all_combos, 10)))
['ABCD1FGH', 'ABCDE1GH', 'ABCDEF1H', 'ABCDEFG1', '2BCDEFGH', 'A2CDEFGH', 'AB2DEFGH', 'ABC2EFGH', 'ABCD2FGH', 'ABCDE2GH']

答案 1 :(得分:0)

每次重新初始化列表。

while y < len(letters):
  s = list(letters)
  s[y] = '1'
  y = y + 1
  dosomethingwith(s)

答案 2 :(得分:0)

string = 'ABCDEFG'
dig = []

for i in range(1,8):
    dig.append(str(i))
    for letter in string[:]:
        print string.replace(letter,dig[i-1])