"Why do we use a built-in function, `len()` to find the length of a list but a method, `.count()` to find how often a value occurs?
"Why aren't they either both methods or both built-in functions?"
Great question asked in a session I was running this week…
The discussion led to what seems like an inconsistency
List is not the only data type that has a `.count()` method
And `len()` doesn't work with all data types, either
So, why don't we treat them in the same way?
`list.count()` and `str.count()`, for example, are different methods that perform a similar task
But is it that different when using `len()`?
Although we use the same built-in function `len()` on several different data types, the hard work is done by the data type's `.__len__()` method
`len([2, 4, 6])`
calls
`[2, 4, 6].__len__()`
and
`len("Hello!")`
calls
`"Hello!".__len__()`
So, behind the scenes, finding the length of data structure is handled by a method, too, even if you're using the built-in function `len()`
The `len()` built-in function gives us a convenient was of accessing the `.__len__()` method
So why is there a `len()` built-in function but not one for counting the number of occurrences of an item, say
These are language design decisions
Finding the length of a _sized_ object was considered worth having a built-in function for, but for anything other than the most common actions, methods are good enough!
In fact, there are cases where we can find both options available
For example, if you want to sort a list, you can either use:
`my_list.sort()`
or
`sorted(my_list)`
…although in this case there's an important difference
Do you know what it is?
Another example where you can either use a method or a function is copying a list. You could use the method:
`my_list.copy()`
or the function that's in the `copy` module
`copy.copy(my_list)`
We could try to justify all of these design decisions. But you may be better off just accepting that that's the way it is!