Removing duplicates from individual strings in a list

Viewed 220

I'm attempting to write a python program that if given a list of strings, will remove duplicate characters from the individual strings of the list. My work so far is:

#program: removeduplicates.py

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-lst", nargs='+', type=str, required=True)
xyz = parser.parse_args()
duplist = xyz.lst

def duplicate_destoryer(duplist):
    finallist = []
    for word in duplist:
        x = set()
        list = []
        for ch in word:
            if ch not in x:
                set.add(ch)
                list.append(ch)
        finallist.append(list)

    return finallist


if __name__ == "__main__":
    print(duplicate_destoryer(duplist))

In my command line I input

python removeduplicates.py -lst aarrtt ddwwtt

and my desired output is(doesn't matter if in list brackets or simply written out):

art dwt

The code I wrote makes sense to me logically, but I keep getting the error descriptor 'add' for 'set' objects doesn't apply to a 'str' object That is fair and all but as I do further research I feel like I keep coming across more and more examples of code where set.add() is being used with string objects.

Could someone point me in the right direction or tell me what I'm doing wrong here?

3 Answers

You are very very close. Just need to use following:

x.add(ch)

instead of:

set.add(ch)

That would fetch a list of lists as output as opposed to a list of strings you would expect. To correct that you can do:

finallist.append(''.join(list))

instead of:

finallist.append(list)

Note that you should not be using list for variable name. It's is a Python built-in.

The issue as pointed out is that you are using

set.add(ch)

And set is making reference to the set class, and not the instance. The fix for your code would be:

x.add(ch)

Just so you know this could also be done in one line at the cost of making the code less readable and you could lose the order of the character input:

>>> words = ["aarrtt", "ddwwtt"]
>>> ["".join(set(list(word))) for word in words]
['art', 'dwt']

First we convert the string into a list of characters by casting it to a list. Then we delete repeated characters casting the list to a set, and then we transform it back to a string using the join method. We do all this inside a comprehension list, iterating over each of the incoming strings.

There are two things going on here:

  1. You can't add to 'set' as your set instance is 'x'. So, instead of set.add(ch), replace it with x.add(ch)
  2. You are collecting your output in a list of lists, which is not what you want. Instead, you should make a list of strings to collect your output.

Here is the modified version with the desired output:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-lst", nargs='+', type=str, required=True)
xyz = parser.parse_args()
duplist = xyz.lst

def duplicate_destoryer(duplist):
    finallist = []
    for word in duplist:
        x = set()
        output = ""
        for ch in word:
            if ch not in x:
                x.add(ch)
                output += ch
        finallist.append(output)

    return finallist


if __name__ == "__main__":
    print(duplicate_destoryer(duplist))
Related