Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't the 'len' function inherited by dictionaries and lists in Python

Tags:

python

example:

a_list = [1, 2, 3]
a_list.len() # doesn't work
len(a_list) # works

Python being (very) object oriented, I don't understand why the 'len' function isn't inherited by the object. Plus I keep trying the wrong solution since it appears as the logical one to me

like image 548
Franck Mesirard Avatar asked Sep 17 '08 14:09

Franck Mesirard


People also ask

Why isn't Len a method in Python?

Python has first-class functions, so len is actually an object. Ruby, on the other hand, doesn't have first class functions. So the len function object has it's own methods that you can inspect by running dir(len) .

What does the LEN function return for dictionaries?

The method len() gives the total length of the dictionary. This would be equal to the number of items in the dictionary.

How does LEN () work in Python?

Python len() Function The len() function returns the number of items in an object. When the object is a string, the len() function returns the number of characters in the string.

Does the LEN function work on sets?

The len() Python function counts the number of items in an object. The object can be a string, tuple, dictionary, list, sets, array, and many more.


2 Answers

Guido's explanation is here:

First of all, I chose len(x) over x.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) into x*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 read x.len(), I have to already know that x is some kind of container implementing an interface or inheriting from a class that has a standard len(). Witness the confusion we occasionally have when a class that is not implementing a mapping has a get() or keys() method, or something that isn’t a file has a write() method.

Saying the same thing in another way, I see ‘len‘ as a built-in operation. I’d hate to lose that. /…/

like image 174
Jim Avatar answered Oct 21 '22 02:10

Jim


The short answer: 1) backwards compatibility and 2) there's not enough of a difference for it to really matter. For a more detailed explanation, read on.

The idiomatic Python approach to such operations is special methods which aren't intended to be called directly. For example, to make x + y work for your own class, you write a __add__ method. To make sure that int(spam) properly converts your custom class, write a __int__ method. To make sure that len(foo) does something sensible, write a __len__ method.

This is how things have always been with Python, and I think it makes a lot of sense for some things. In particular, this seems like a sensible way to implement operator overloading. As for the rest, different languages disagree; in Ruby you'd convert something to an integer by calling spam.to_i directly instead of saying int(spam).

You're right that Python is an extremely object-oriented language and that having to call an external function on an object to get its length seems odd. On the other hand, len(silly_walks) isn't any more onerous than silly_walks.len(), and Guido has said that he actually prefers it (http://mail.python.org/pipermail/python-3000/2006-November/004643.html).

like image 24
Eli Courtwright Avatar answered Oct 21 '22 01:10

Eli Courtwright