Aditya Pandey
Aditya Pandey

Reputation: 140

Differect Result with Replace method in Python

Context : I'm writing a program to find 1st non-repeating letter in a string.

TEST CODE I need to implement following logic :

s = "iiiiiiitya"
if 'i' in s:
    s = s.replace('i','')
print(s)

OUTPUT : tya

Which is fine. It removes all the occurances of 'i' from the string. That is what I wanted.

PROBLEM : But as soon as I start to implement same logic in my actual program, the function doesn't work the same i.e. It only removes only 1st occurance of the perticulare letter and hence my logic fails.

def non_rep(s):
    for el in s:
        if el in s[1:]:
            s = s.replace(el,'')
        else:
            return el
    return "No such case is matched"
str = "adiiiityda"
ch = non_rep(str)
print(ch)

OUTPUT : i

EXPECTED OUTPUT : t

Why does it behave in such way, I tried a lot, but it works like it should in the first(test) code and when I implement it into program it behave differently.

Upvotes: 0

Views: 81

Answers (4)

Fatemeh Mansoor
Fatemeh Mansoor

Reputation: 565

You should note that string is immutable, hence you can not change it on loop it won't behave the way you want:

def non_rep(s):
    for el in s:
        if el in s[1:]:
            s = s.replace(el,'')
    if len(s)>0:
        return s[0]
    return "No such case is matched"

str = "adiiiityda"
ch = non_rep(str)
print(ch)

Upvotes: 1

Burstein Omer
Burstein Omer

Reputation: 79

You can use the function count on strings in Python as the following:

def non_rep(s):
    for char in s:
        if s.count(char) == 1:
            return char

Upvotes: 2

j1-lee
j1-lee

Reputation: 13939

The following implements your idea using while instead:

def non_rep(s):
    while s: # while s is non-empty
        el = s[0] # get the first character
        if el in s[1:]: # if the character is found in another place
            s = s.replace(el, '') # remove all of them
        else: # if not repeated
            return s[0] # return that
    return 'No such case is matched' # this is reached when depleted

print(non_rep("adiiiityda")) # t
print(non_rep("aabbcc")) # No such case is matched

It is generally advised not to remove an item in a for loop. If you put print(el, s) right after for el in s:, you would see what is happening. You would find out that el just follows the original string adiiiityda. So at the fourth iteration, el is 'i' while s is 'ty'. Your code cannot find this 'i' in 'ty', so it returns 'i', which is not what you want.

Upvotes: 1

mozway
mozway

Reputation: 261590

You can use collections.Counter to get the counts, then keep only the unique values:

from collections import Counter

s = "iiiiiiitya"

c = Counter(s)
''.join([i for i in c if c[i]==1])

output: tya

Upvotes: 1

Related Questions