Frequency Count : CODE CHALLENGE: DICTIONARIES

https://www.codecademy.com/courses/learn-python-3/lessons/python-functions-dictionaries-cc/exercises/frequency-count - challenge 8 frequency count

Hey everyone, hope you’re living the dream!

Basically, I understand 99% of the code I’ve written here, but there are some crucial bits I don’t.

def frequency_dictionary(words):

  seen = set()

  seen_add = seen.add

  frequency = [words.count(word) for word in words if not (word in seen or seen_add(word)) ]

  return dict(zip(seen, frequency))

I pretty much made all this code by myself, the two portions I researched online to incorporate are:

seen_add = seen.add

and

...if not (word in seen or seen_add(word))]

I’ve played about and know without these bits my code breaks. I pretty much can understand the if condition. Just don’t really know what seen.add is doing.

Cheers in advanced

If this is a lesson why not implement it with code that you understand? Whilst there could be other options to solve a problem you’ll likely make your own life harder if you “write” your code like this. I’d suggest solving it yourself before looking up alternative methods.

If you’re just trying to understand a small segment of code then just say so and keep it as simple as possible.

The . notation is used like this for accessing attributes so it’s reasonable to assume this an attribute of the object identified by seen. Perhaps you should check the docs for details of the relevant attributes for a set.

Completely agree with doing it how the lessons have taught, and I did this. I wanted to improve on the code though and thought a comprehension was a great way to do this. I believe research, of different python codes and methods, is a great way to learn and when you find something you don’t understand you must learn how it works encase you encounter something like that in the future.

I achieved creating the code, with a little research, which took me to a method online on how someone used the seen.add portion of this code I incorporated.
This post was to see if other people can highlight what I’m not understanding with the two highlighted pieces of code, more so the first - seen.add. Plus a second opinion is always best.

Since your post, I have had more of a dive into this, and the main thing that was confusing me is that .add hasn’t got parentheses. I thought the same that this was an attribute possibly but it isn’t, I think. Rather a method invoked without parentheses, in which is to only pass a reference to the method instead… This is what my understanding of it is currently. I’d love to hear thoughts, because I haven’t experienced this before, and second opinions are always appreciated.

1 Like

Aye, like normal functions, object attributes can be assigned to various names. Though a data attribute would assign to the object referenced by the attribute obj.attr_a = 10; x = obj.attr_a would reference integer object 10).

# assigning another name to the same function...
def myfunction(x):
    return x + 3
new_name = myfunction
print(new_name(10))
Out: 13

# Let's consider an instance method used before...
lst = ['a', 'b', 'c']
add_lst = lst.append
add_lst('d')
print(lst)
Out: ['a', 'b', 'c', 'd']
# Note that is addressing the method of object `lst` specifically

I guess the name assignment was used to try and improve readability but I’m not sure that it achieves it. It can sometimes be useful but it does risk obscuring your code a little if abused.

1 Like

what about using .count()?

Or, does this lesson specifically say to not use that method? (I cannot recall)

https://www.programiz.com/python-programming/methods/string/count

Cheers for that mock example. That is a massive help and clearly breaks it down in a simplistic manner to digest. Experimenting with what you’ve given me with other examples:

dictionary = {"billy the kid": 24}
add_dictionary = dictionary.update
add_dictionary({"bob":22, "gandolf": 110})
print(dictionary)
#output
{"billy the kid": 24, "bob": 22, "gandolf": 110}

I’ve now noticed because of you the redundancy in the code I’ve got. The first line:

seen_add = seen.add

Can be removed. Then the if loop condition can get rid off the seen_add(word) and use the normal seen.add(word). I’m literally just passing the functionality as a reference to a new variable. Hope what I’ve written makes sense, I’m far better at visual understanding than written.

I completely agree with your comment about readability and believe this wouldn’t be deemed a very pythonic piece of code. It does look a little bit confusing at first, and by the python philosophy, it should always do its best to be explicit in writing.

I think it reads much better as just seen.add() too. Have you tried testing this function out with some simple examples yet? Something has just occurred to me about this problem and it’ll almost inevitably cause problems with this function.

Hint

If you haven’t already looked into it then consider “what is the order of a set?”…

Yeah, I’ve noticed an issue :laughing: with the method currently every time the function is run you have a random order, since sets don’t save the order they’re given

1 Like

I’ve already been using it, but I’ve realised with your comment I could condense my main bit of code to:

frequency = [words.count(word) for word in words]
return dict(zip(words, frequency))

Which actually does the trick, because I forgot dictionaries naturally get rid of duplicates as well. Was using a set() because of that reason, but never needed it :laughing: I’ve basically overcomplicated how I wanted to do this code, but have learnt from it.

1 Like

I just wanna share this link about the reason of using a local variable seen_add instead of using seen.add directly.

2 Likes