Reputation: 451
I have a string:
'ABCDEFGH'
I want to cycle through the string and, one by one, replace each character with one of 4 characters (1,2,3,4):
'ABCDEFGH'
'1BCDEFGH'
'A1CDEFGH'
'AB1DEFGH'
etc
'2BCDEFGH'
'A2CDEFGH'
'AB2DEFGH'
etc and so forth. However everytime I try, I end up altering the original string and my output ends up being strings of 1s!
'1111111'
Example code below:
letters = 'ABCDEFGH'
s = list(letters)
y = 0
while y < len(s):
s[y] = '1'
y = y + 1
Upvotes: 0
Views: 992
Reputation: 1121356
Rather than change a list you reuse between iterations, produce a new list each time and replace the one character:
for i in range(len(letters)):
s = list(letters)
s[i] = '1'
print(''.join(s))
You can combine this with a nested loop:
for digit in '1234':
for i in range(len(letters)):
s = list(letters)
s[i] = digit
print(''.join(s))
In essence you are creating the product of '1234'
and a position from range(len(letters))
, so you could use itertools.product()
to make that a single loop:
from itertools import product
for digit, pos in product('1234', range(len(letters))):
s = list(letters)
s[pos] = digit
print(''.join(s))
With a little enumerate()
trickery you could make this a one-liner generator expression to produce all combinations:
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))))
This builds a new list on the fly by iteration over letters
, swapping out the one character at position pos
for the digit.
Demo:
>>> 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']
Upvotes: 3
Reputation: 580
string = 'ABCDEFG'
dig = []
for i in range(1,8):
dig.append(str(i))
for letter in string[:]:
print string.replace(letter,dig[i-1])
Upvotes: 0
Reputation: 798526
Reinitialize the list each time.
while y < len(letters):
s = list(letters)
s[y] = '1'
y = y + 1
dosomethingwith(s)
Upvotes: 0