I have a file named numbers.txt that looks something like this:

1243#74656453634#6356#56456456#565#1212121#78384
83#457#090#720347###24273#18712#478230478#57117
58125671#47464#74647#46474647#19192938#828##2583
5#2948284#6010203040#

I need to replace all of the '#' symbols with '!'. Then I need to replace 3 of the'!' symbols to '@' but not knowing which ones. It could be the 2nd, 5th, 15th or 1st, 6th, 8th, or......etc. What I need is some kind of loop, I guess, that will try replacing the positions as it goes: try replacing positions 1,2,3 then check the file, if not the correct replacements, try 1,2,4 check and if not correct then try 1,2,5 etc until all combinations are checked. I have this which will accomplish some of it....it will replace all of the '#' with '!' and I can get it to replace certain positions with a posList = [1,2,3].

def replace_pos(s, old, new, posList):
    idx = -1
    count = 0
    while True:
        """
        s.find() returns the position of the substring.
        When the end of string is reached and no more
        occurrances of substring are found, s.find()
        returns -1.
        """
        idx = s.find(old, idx+1)
        count += 1
        if idx == -1:
            return s
        elif count in posList:
            s = "%s%s%s" % (s[:idx],new,s[(idx+len(old)):])   
 
f = open("numbers.txt","r")
s = f.read()
s1 = s.replace("#","!")
oldStr = "!"
newStr = "@"
posList = [1,2,3]
s2 = replace_pos(s1, oldStr, newStr, posList)
print s2

The problem is that I don't want to do something like this:

comb_list = [[1,2,3], [1,2,4], [1,2,5], [1,3,4], [1,4,5], [2,3,4], [3,4,5]]
 
for clist in comb_list:
    s1 = replace_pos(s, oldStr, newStr, clist)

because of all of the possible combinations I'd have to enter in the comb_list. Isn't there an easier way to do this? Besides it doesn't quite accomplish my goals.

Recommended Answers

All 8 Replies

The first goal is met with simple replace:

>>> mystring="""1243#74656453634#6356#56456456#565#1212121#7838483
#457#090#720347###24273#18712#478230478#5711758125671#47464
#74647#46474647#19192938#828##25835#2948284#6010203040#"""
>>> mystring2 = mystring.replace("#","!")
>>> print mystring2
1243!74656453634!6356!56456456!565!1212121!7838483
!457!090!720347!!!24273!18712!478230478!5711758125671!47464
!74647!46474647!19192938!828!!25835!2948284!6010203040!

The second goal is unclear. Do you want to replace the first three ! with @, or what?

Jeff

You can split on the "#" and do a single replace for both characters if that helps That's a single pass through the number string for the split() and a single join to put it back together instead of multiple lookup passes to find and replace each number. Instead of the "while()", a "for each_number in test_list", keeping the ctr as well, might be slightly faster over a very large data set since you will not have to find a specific member of the list i.e. each_number is used instead of test_list[ctr].

test_str="1243#74656453634#6356#56456456#565#1212121#7838483#457"
test_str += "#090#720347###24273#18712#478230478#5711758125671#47464"
test_str += "#74647#46474647#19192938#828##25835#2948284#6010203040#"

numbers_list=[ 1, 3, 6, 9, 10]
test_list=test_str.split("#")
stop = len(test_list)
ctr=0
final_str=""
while ctr < stop:
   final_str += test_list[ctr]
   if ctr in numbers_list:
      final_str += "@"
   else:
      final_str += "!"
   ctr += 1
print final_str

Thank you both for your replies. I'm sorry I wasn't clear in what I need to do, or maybe my code is throwing things off because I'm not sure how to resolve this.
Here is a file that I have, numbers.txt:

1243#74656453634#6356#56456456#565#1212121#78384
83#457#090#720347###24273#18712#478230478#57117
58125671#47464#74647#46474647#19192938#828##2583
5#2948284#6010203040#

I'm going to skip past the parts that I can code and put it a different way since I'm probably going about it wrong anyway. Let's say you have the above text and need to change the 1st, 2nd, 3rd '#' symbols to '@', print it and once it's done also print "Hello World!". Now the program isn't done running because you now have to have it start over and change the 1,2,4 print and then print "Hello World!", then do it again but this time replacing positions 1,2,5 and printing and so on until all combinations are checked. The print outs should look like this:

# Replacing 1,2,3 positions of '#' with '@'
>>>
1243@74656453634@635@56456456#565#1212121#78384
83#457#090#720347###24273#18712#478230478#57117
58125671#47464#74647#46474647#19192938#828##2583
5#2948284#6010203040#
Hello World!

#First code undone and now replacing 1,2,4
1243@74656453634@6356#56456456@565#1212121#78384
83#457#090#720347###24273#18712#478230478#57117
58125671#47464#74647#46474647#19192938#828##2583
5#2948284#6010203040#
Hello World!

#code undone and now replacing 1,2,5
1243@74656453634@6356#56456456#565@1212121#78384
83#457#090#720347###24273#18712#478230478#57117
58125671#47464#74647#46474647#19192938#828##2583
5#2948284#6010203040#
Hello World!

# Skipped ahead to the final one where the last 3 positions are changed.
1243#4656453634#6356#56456456#565#1212121#78384
83#457#090#720347###24273#18712#478230478#57117
58125671#47464#74647#46474647#19192938#828##2583
5@2948284@6010203040@
Hello World!

So it's a little more like that that I'm after. Like I said, I can change the initial symbols and can change certain positions [1,2,3] and have it print and print "Hello World" but I can't get it to keep running and printing until all combo's are tried.

This is the code modified to do 3 at a time in the way that I think you explained.

test_str="1243#74656453634#6356#56456456#565#1212121#7838483#457"
test_str += "#090#720347###24273#18712#478230478#5711758125671#47464"
test_str += "#74647#46474647#19192938#828##25835#2948284#6010203040#"

test_list=test_str.split("#")
##   subtract one from stop because the last letter is a "#"
stop = len(test_list) - 1
for j in range( 0, stop-2 ):
   for k in range( j+1, stop-1 ):
      for m in range( k+1, stop ):
         numbers_list = [ j, k, m ]
         ctr=0
         final_str=""
         while ctr < stop:
            final_str += test_list[ctr]
            if ctr in numbers_list:     ## or ==j, or ==k, or == m if you want
               final_str += "@"
            else:
               final_str += "#"        ## or "!" if you want
            ctr += 1
         print final_str
         print j, k, m, "Hello World\n"

woooee, that is absolutely what I'm looking for! Thank you....totally off from the way I was trying to do it! Bravo

Mark this as solved so others don't wander in here trying to fix this for you

=]

Oh ok linux, I didn't realize I had to do that but before I do I wanted to ask one more question about my post.....is there a way to do this using a recursive function instead of a loop?

You can replace the for loop with a function to do this using recursion. While this board will help with homework, not many here will do the whole thing for you.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.