Might be a weird question. But I have been scratching my head over why if you want to get the length of a list you can't simply say list.len() and you have to pass the list to len() to get its size? And where this len() is actually coming from?
Python has first-class functions, so len is actually an object.
There is a built-in function called len() for getting the total number of items in a list, tuple, arrays, dictionary, etc. The len() method takes an argument where you may provide a list and it returns the length of the given list.
The function len() is one of Python's built-in functions. It returns the length of an object. For example, it can return the number of items in a list.
The runtime complexity of the len() function on your Python list is O(1). It takes constant runtime no matter how many elements are in the list. Why? Because the list object maintains an integer counter that increases and decreases as you add and remove list elements.
You can get the length of a lot of items. Lists, dicts, sets, other collections. So the builtin len()
that calls type(obj).__len__(obj)
internally gives you a standard API to get the length.
If all those collection types had a len()
method that was called directly there would be nothing to prevent someone from creating a custom collection class that uses e.g. .length()
or a .length
property.
Here's the explanation from Guido van Rossum, the creator of Python:
First of all, I chose
len(x)
overx.len()
for HCI reasons (def __len__()
came much later). There are two intertwined reasons actually, both HCI:(a) For some operations, prefix notation just reads better than postfix -- prefix (and infix!) operations have a long tradition in mathematics which likes notations where the visuals help the mathematician thinking about a problem. Compare the easy with which we rewrite a formula like
x*(a+b)
intox*a + x*b
to the clumsiness of doing the same thing using a raw OO notation.(b) When I read code that says
len(x)
I know that it is asking for the length of something. This tells me two things: the result is an integer, and the argument is some kind of container. To the contrary, when I readx.len()
, I have to already know that x is some kind of container implementing an interface or inheriting from a class that has a standardlen()
. Witness the confusion we occasionally have when a class that is not implementing a mapping has aget()
orkeys()
method, or something that isn't a file has awrite()
method.Saying the same thing in another way, I see 'len' as a built-in operation. I'd hate to lose that. I can't say for sure whether you meant that or not, but 'def len(self): ...' certainly sounds like you want to demote it to an ordinary method. I'm strongly -1 on that.
it actually comes from __len__()
:
In [15]: lis=[1,2,3]
In [16]: lis.__len__()
Out[16]: 3
object.__len__(self)
:
Called to implement the built-in function len(). Should return the length of the object, an integer >= 0. Also, an object that doesn’t define a nonzero() method and whose len() method returns zero is considered to be false in a Boolean context.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With