4
\$\begingroup\$

We scan the string from left to right finding the unique characters. We also need to find the non unique characters and count them on how many times they appear. If we can’t find any unique characters, then we return an empty list.

Here’s the code:

def unique_occ(the_str):
    res1 = list(the_str)
    unique_letter = []
    non_unique = []
    for i in res1: 
        #there lies the issue
        #as you can see, the loop should take care of the counting. 
        #But if is this is the first time that the letters appears
        #, well there is an issue.     
        if i not in unique_letter:
            unique_letter.append(i)
        else:
            non_unique.append(i)

    #from that, I need to sort the letters as the for loop is not doing 
    #what it is supposed to do

    unique_sort = [elts for elts in unique_letter if elts not in non_unique]
    non_unique1 = [elts for elts in unique_letter if elts in non_unique]

    #the worst part is I need to sort again the letters that have appeared more than once and concatenate them into the list again

    non_unique = non_unique + non_unique1
    non_unique2 = {i:non_unique.count(i) for i in non_unique}

    #finally, the letters have been sorted between the unique and the non unique 
    return 'unique letter is {} and non unique letter is {}'.format(unique_sort,non_unique2)        

The code works.

There is probably an easier way but I don't see how, at least for now. I'm unsatisfied about the pythonic way of the code.

Any help or insight will be welcomed.

\$\endgroup\$
7
\$\begingroup\$

A simple and pythonic way to accomplish this is using collections.Counter. It's an easy way to count elements in an iterable. Have a look:

from collections import Counter

def unique_letters(string: str) -> str:
    """
    Finds all the unique/non unique letters in the string
    """
    letters = Counter(string)

    unique = [key for key in letters if letters[key] == 1]
    non_unique = {key: letters[key] for key in letters if letters[key] > 1}
    return f"Unique: {unique} | Not Unique: {non_unique}"

This also takes advantage of f-strings, allowing you to directly implement variables into your strings. It's a personal preference, but to me it looks a lot nicer than using .format().

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Hi @Linny, omg!!! so simple. ty. \$\endgroup\$ – Andy K Feb 24 at 19:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.