I would use comprehensions and zip. I've commented the code, but feel free to ask if something is unclear.
my_str = 'ATTTTACGTA'
# This loop will check that
# - the casting to int is ok
# - there are only two numbers inputted
# - stop >= start
# - start > 0
# - stop < len(my_str)
while True:
try:
start, stop = map(int, raw_input(
'Please enter start and stop index separated by whitespace\n').split())
if stop < start or start < 0 or stop > len(my_str):
raise ValueError
break
except ValueError:
print 'Bad input, try again'
# Loop over all chars, check if the current index is inside range(start, stop).
# If it is, add (char, '?') to the array, if not, add ('?', char) to the array.
#
# This would give you an array of something like this:
# [('?', 'A'), ('?', 'T'), ('T', '?'), ('T', '?'), ('?', 'T'), ('?', 'A'),
# ('?', 'C'), ('?', 'G'), ('?', 'T'), ('?', 'A')]
#
# By using zip(*array), we unpack each element, and saves the first indexes as
# one list, and the second indexes as another, giving you a list like this:
#
# [('?', '?', 'T', 'T', '?', '?', '?', '?', '?', '?'),
# ('A', 'T', '?', '?', 'T', 'A', 'C', 'G', 'T', 'A')]
chars = zip(*((c, '?') if i in range(start, stop) else ('?', c)
for i, c in enumerate(my_str)))
# ''.join is used to concencate all chars into two strings
my_lst = [''.join(s) for s in chars]
print my_lst
Sample output:
Please enter start and stop index separated by whitespace
4
Bad input, try again
Please enter start and stop index separated by whitespace
5 4
Bad input, try again
Please enter start and stop index separated by whitespace
e 3
Bad input, try again
Please enter start and stop index separated by whitespace
4 5
['????T?????', 'ATTT?ACGTA']