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 (2016, retired 2019) Dictionaries Dictionary Iteration

horus93
horus93
4,333 Points

Curious about why using len to count keys vs values in a dict requires a different approach.

So I'm working on the last 5 part challenge for this section, and the first thing it asks was to create a function named num_teachers that would take a single argument, a dictionary of teachers the background tester would presumably run through it as with most challenges, and wanted me to return (if i remember right) a total number of teachers (keys) in the dict.

My brain wasn't working for a bit late last night so I slept on it and found the solution rather quickly this morning, as usual, when I'm tired I tend to overthink things and instead wound up with a much shorter solution in the form of

==========

tt = {}

def num_teachers(tt):
    return len(tt.keys())

==========

Ok, so far so good, then the second one seemed like it was asking the same question, except wanting me to return the total # of courses (values) for all the teachers. So, obviously I'm thinking (this is too easy, why would they ask me the same question twice in a row instead of just having me create both the functions in one step? But I figured, hey, maybe your overthinking it, just try it anyway.

==========

tt = {}

def num_teachers(tt):
    return len(tt.keys())

def num_courses(tt):
    return len(tt.values())

==========

no such luck, wound up with the same problem I had when I tried my first solution to the first step which was that the function didn't return the right number of teachers, after a little searching online I came across a solution using 'sum' and 'map', but I can't for the life of me remember going over map at least. I'm pretty sure I remember sum coming up at one point in the earlier lessons, but from what I've read map is part and parcel for tuples which is the next section over.

Anyway, that solution didn't take long to find and it looked like this

=============

tt = {}

def num_teachers(tt):
    return len(tt.keys())

def num_courses(tt):
    return sum(map(len, tt.values()))

=============

And I was wondering why it'd be necessary to approach it like that rather than simply doing a len for the dict values like I can with the keys? Would it run into a problem with keys that hold multiple values, instead just returning the count as 1 each time without using sum and map? My gut is telling me that's probably the case, but i'd like someone more learned to weigh in on the matter.

[MOD: added ```python formatting -cf]

1 Answer

andren
andren
28,558 Points

The issue does indeed stem from the fact that the value contains multiple items, while the key only contains one. The key represents one teacher, so by counting the number of keys you find out the number of teachers. The values on the other hand are lists of courses, one list does not equal one course. So counting the number of values does not give you the number of courses.

It is extremely rare for a key to contain multiple elements, but it is in theory possible (using a tuple or something) and yes you would run into the same type of issue.

Also while using map works it is not the only solution. There are a number of solutions that would not have required using unknown methods, for example you could have looped through each of the values and counted the number of items in each value. Like this:

def num_courses(tt):
    courses = 0
    for value in tt.values():
        courses += len(value)
    return courses