Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Python Collections (Retired) Dictionaries Word Count

My code works, but the challenge window tells me "didn't get the right count in some of the words.

My code works, but the challenge window tells me "didn't get the right count in some of the words.

word_count.py
# E.g. word_count("I am that I am") gets back a dictionary like:
# {'i': 2, 'am': 2, 'that': 1}
# Lowercase the string to make it easier.
# Using .split() on the sentence will give you a list of words.
# In a for loop of that list, you'll have a word that you can
# check for inclusion in the dict (with "if word in dict"-style syntax).
# Or add it to the dict with something like word_dict[word] = 1.
myString = "this is not what this is"

def word_count(string):
    counter = 1
    myList = string.split()
    myDict = dict()
    for word in myList:
        if word in myDict:
            myDict[word] = counter + 1
        else:
            myDict.update({word:counter})
    return myDict

word_count(myString)

Sergio,

Follow the logic of your variable "counter". It seems like you want to increase the counter for that 'word' each time you encounter it again. It looks to me as if you are taking the current value of the global variable 'counter' (which is set outside the for loop) and adding one to it. I think you want to add one, "variable += 1", to the dictionary count of that word myDict[word]. So something like:

myDict[word] += 1

Ron

It worked! Thank you, Ron.

1 Answer

For a really fun and succinct way of solving this challenge you can use a "dictionary comprehension", which generates a dict object based on key-value pairs generated from an iterable object such as a list. That sounds scary but it isn't too hard to implement. Conceptually the dictionary comprehension works like this

{new dictionary} = {key:value for key in iterable}

In our case the iterable is the list object containing the words from the input string myString You already converted myString into a list object myList with the split() function. The only additional piece of the puzzle is to know about the list method called count(). It tells you how many times the argument occurs in the list its operating on. For example [1, 1, 3, 5, 6, 1].count(1) returns 3 since value 1 occurs three times in the list.

Now, putting all of this together we obtain:

myDict = {key:myList.count(key) for key in myList}

print myDict {'this': 2, 'not': 1, 'is': 2, 'what': 1}

The dictionary comprehension is going through each item in myList, assigning that value to the variable key and then generating what will become the next key-value pair to be added to myDict. The key variable in the comprehension supplies the key for each dictionary item, i.e. the value that's on the left side of the : symbol. The myList.count(key) expression generates the value that goes on the right side of the : symbol.

It is true that the above line of code is a bit inefficient since key:myList.count(key) will be generated for each item in myList, which contains duplicates, which is kind of the whole point of this exercise. LOL. So if "this" occurs twice in myList, the dictionary comprehension will generate 'this':2 twice, which is superfluous.

To improve on this, we can create a set object from the list object. When you make a set from a list, you get only the unique items from that list. For example if a = [1, 1, 1, 2, 3, 4, 5], set(a) will be [1, 2, 3, 4, 5]

So let's create a set from myList: my_set = set(myList)

my_set (['this', 'not', 'is', 'what'])

Now let's rewrite our dictionary comprehension to iterate through the unique valued my_set object instead of the original myList, which contains duplicate values and causes the dictionary comprehension to generate key-value pairs unnecessarily.

myDict = {key:myList.count(key) for key in my_set}

print myDict {'this': 2, 'not': 1, 'is': 2, 'what': 1}

Note that in the dictionary comprehension we still refer to the original list myList to obtain the count of each of the unique values in my_set.

Nifty, yes?