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!
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

Ryan Carson
23,287 PointsBetter way to solve this Python Code Challenge?
It took me awhile to solve this Code Challenge. Finally did (yay!) but I have a feeling my solution isn't very elegant. Suggestions welcome!
def word_count(my_string):
my_string = my_string.lower()
word_list = my_string.split()
word_dict = {}
count = 0
for word in word_list:
if word in word_dict:
count = word_dict[word]
count += 1
word_dict.update({word: count})
else:
word_dict[word] = 1
return word_dict
4 Answers

Dino Paškvan
Courses Plus Student 44,107 PointsHello, Ryan! I wouldn't say there's a necessarily better way, but you can make the whole function less verbose. I'll add comments to your code first:
def word_count(my_string):
my_string = my_string.lower()
word_list = my_string.split()
word_dict = {}
count = 0 # You don't really need this outside of the for loop
for word in word_list:
if word in word_dict:
count = word_dict[word] # Instead of doing all of this
count += 1 # you can increment the value for that key
word_dict.update({word: count}) # directly - word_dict[word] += 1
else:
word_dict[word] = 1
return word_dict
So that would turn into:
def word_count(my_string):
my_string = my_string.lower()
word_list = my_string.split()
word_dict = {}
for word in word_list:
if word in word_dict:
word_dict[word] += 1
else:
word_dict[word] = 1
return word_dict
If you want to make it even shorter, you can get rid of the word_list
variable and iterate over the return value of the chained .lower().split()
method call:
def word_count(my_string):
word_dict = {}
for word in my_string.lower().split():
if word in word_dict:
word_dict[word] += 1
else:
word_dict[word] = 1
return word_dict

Jason Anello
Courses Plus Student 94,610 PointsHi Ryan,
You can increment the count in your if
block like this: word_dict[word] += 1
This would grab the current count for that key, add one to it and store it back in that same key.
This can replace the 3 lines you have in your if
block.
You can then remove the count
initialization before the for
loop.

Chris Shaw
26,663 PointsHi Ryan,
Going off Jason's answer which is the same thought process I had you can shorten your code all the way down to...
def word_count(my_string):
word_dict = {}
for word in my_string.split():
if word in word_dict:
word_dict[word] += 1
else:
word_dict[word] = 1
return word_dict

Kenneth Love
Treehouse Guest TeacherSince we talked about this in work chat, I'll post my two alternate solutions. Let's assume this string for all examples:
sentence = "If the facts don't fit the theory change the facts"
Using Counter
So Python has this library named collections
that stores a lot of alternate collection types. One of those is Counter
which, well, counts things.
from collections import Count
def word_count(my_string):
words = my_string.lower().split()
counts = Counter(words)
return counts
>>> output = word_count(sentence)
Counter({'if': 1, 'the': 3, ...})
What's really awesome about Counter
, though is being able to do this:
>>> output.most_common(1)
[('the', 3)]
Using setdefault
Python's dict
object has a weird (to me) method called setdefault()
that let's you set a default value if the dict doesn't have the key you want. Otherwise it returns the value of the key. Say:
>>> my_dict = {'a': 5}
>>> my_dict.setdefault('a', 10)
5
>>> my_dict.setdefault('b', 10)
10
>>> my_dict
{'a': 5, 'b', 10)
So you can use that for word_count()
def word_count(my_string):
words = my_string.lower().split()
counter = {}
for word in words:
counter[word] = counter.setdefault(word, 0) + 1
return counter
The counter[word] = counter.setdefault(word, 0) + 1
line trips some people up. We're setting the default to 0 and then incrementing it by 1. Basically we've negating the try
/except
that's needed for the usual approach.
So why didn't I teach either of these methods? They're way more special-case than using try/
exceptand
.get()` and the like. I'd rather you have common scenario tools than wizzbang special effect tools. But, I guess you can now consider yourself taught these nifty little tools. Be sure to check out collections if you want more neat tools.

Ryan Carson
23,287 PointsThank you sir! :)

Ken Alger
Treehouse TeacherMr. Love;
That is too cool. Didn't know about that in Python.
Mr. Carson;
It is also pretty cool to see you on here sharing the same "struggles" the rest of us have.
Keep up the awesome content, gentlemen.
Ken