Press-F
Press-F

Reputation: 51

Find the most unique characters in a list of strings

Recently joined a python code club, so not a school assignment.

Task:

Write a function coolest_word(words) that returns the coolest word if it exists.

The coolness is defined by how many unique characters a word has.

For example the word "decomposition" has a 10 unique letters. Your job is to find from the given list of words the coolest word and return it.

If the list is empty, return None. If there is a tie, return one of the words.

My solution up till now:

words = ['expectation', 'discomfort', 'half', 'decomposition']
def coolest_word(words):
    length = 0
    unique = ['']
    for i in words:
        if (len(words) != 0 and len(set(i)) > length):
            length = len(set(i))
            unique[0] = i
        else:
            unique[0] = ('None')
    return(unique)  
print(coolest_word(words))

I've chosen to change list to set and afterwards compare unique characters of a set with each other. As set does not take into account duplicate variables it seemed like a good idea.

Whenever for loop finds a longer set(with more variables) it is overwritten into unique set to be memorized and later called upon.

The problem right now is that if the given list is empty unique returns [''], which I do not understand why.

As in the second part if the list is empty I want unique to be overwritten, but it does not do so.

Any thoughts?

Upvotes: 2

Views: 547

Answers (5)

Vinod Kumar Jain
Vinod Kumar Jain

Reputation: 1

very simple approach using unordered_set in c++. Check code below:

#include #include <bits/stdc++.h>

using namespace std;

string coolestword(vector wordList) {

if(wordList.empty()) return "None";

int length = 0;
string retStr = "None";
for(string word : wordList) {
    unordered_set<char> tempSet;
    for(int i=0; i<word.size(); i++){
        tempSet.insert(word[i]);
    }
    if(length<tempSet.size()) {
        length = tempSet.size();
        retStr = word;
    }
}

return retStr;

}

int main() { vector wordList = {"expectation", "discomfort", "half", "decomposition"}; std::cout << coolestword(wordList) << std::endl; return 0; }

Upvotes: 0

Stefan Pochmann
Stefan Pochmann

Reputation: 28606

Simple application of max with both key and default.

def coolest_word(words):
    return max(words, key=lambda w: len(set(w)), default=None)

Demo:

>>> coolest_word(['expectation', 'discomfort', 'half', 'decomposition'])
'decomposition'

>>> [coolest_word([])]   # Wrap in a list because None by itself doesn't get printed
[None]

Upvotes: 6

leqo
leqo

Reputation: 355

If the given list is empty, the entire for loop is skipped. So you just have to initialize unique this way:

unique = ['None']

Also you have to remove the else branch inside the for loop, because it would overwrite the result as soon as you find a word having no duplicate letters (to test what I'm saying, try to shuffle the input list this way:

words = ['expectation', 'discomfort', 'decomposition', 'half']

and you would get 'None' instead of 'decomposition'.

ADDENDUM: you can even simplify your if condition, replacing

if (len(words) != 0 and len(set(i)) > length)

with

if (len(set(i)) > length)

because if len(words) were actually 0 you wouldn't even enter the for loop.

Upvotes: 1

Sociopath
Sociopath

Reputation: 13401

You can use set to get unique elements in a word and len to find out how many unique elements are in word.

words = ['expectation', 'discomfort', 'half', 'decomposition']

def coolest_word(wlist):
    k = {i:len(set(i)) for i in wlist}
    return max(k, key=k.get)

print(coolest_word(words))

Output:

'decomposition'

Explanation

if you do print(k) it will give you

{'expectation': 9, 'discomfort': 9, 'half': 4, 'decomposition': 10}

max(k, key=k.get) will return a key with highest value(max value),

k.get will get the values for a key

eg.

print(k.get("half"))

output:

4

Upvotes: 3

Prashant Kumar
Prashant Kumar

Reputation: 2092

If your input list words is empty, i.ee, words=[], you will not go inside the for loop. And you are not defining what should happen to unique incase input list is empty.

Try this:

words = ['expectation', 'discomfort', 'half', 'decomposition']
def coolest_word(words):
    length = 0
    unique = ['']

    if not words:    # If input list is empty set unique as None.
        unique[0] = 'None'    

    for i in words:
        if (len(words) != 0 and len(set(i)) > length):
            length = len(set(i))
            unique[0] = i
        else:
            unique[0] = ('None')
    return(unique)  
print(coolest_word(words))

But a better way I can suggest would be to initialize the unique list with None, i.e. unique = ['None'] instead of unique = ['']. This way you can keep all your code as it is.

Upvotes: 1

Related Questions