Introduction to len()
00:00
In the previous lesson, I gave an overview of the course. In this lesson, I’ll show you how to use len()
through some examples in the REPL.
00:08
len()
is a built-in function responsible for finding the length of container-like objects. If Python isn’t your first programming language, you might find it odd that len()
is a function. In a lot of other coding languages, it is a method on container-like classes.
00:24
Here’s a quote from Python’s original developer, Guido, on why he decided to do it this way: “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()
.” Out of the box, len()
works on sequence objects, such as strings, bytes, tuples, lists, and ranges.
01:03
It also works on collection objects, such as dictionaries and sets. The len()
function does its magic by calling an underlying special function on a class called __len__()
(dunder len). So in addition to all those things I just mentioned, any class that you or anyone else writes can support len()
if you like.
01:25
Let me start by using the built-in help()
function to show information on the built-in len()
function.
01:33 As you can see, it returns the number of items in a container. Strictly speaking, this means it always returns an integer. You can’t use it on your line class to give the length of your line.
01:44
You can try, but you’ll get an exception if you try to give len()
a float. Trust me, I’ve tried it. Let’s see some examples.
01:54 The length of the string, of a list, of a tuple. How about some stuff that isn’t there? An empty string, an empty list, or some empty brackets. That all kind of makes sense.
02:17
Have you ever used the range()
function inside of a for
loop? It is a special kind of sequence that returns numeric values in counting fashion. Here’s a typical usage.
02:33
In this case, range()
returned from one to less than ten—that’d be nine—which the for
loop iterated through and printed out. If you try to use the range()
on its own without for
loop, you get back a range()
object.
02:50
This would be why I called it a special kind of sequence just a second ago. Like many sequences in Python, you can use len()
on range()
.
03:02
This is the same range()
I used in the for
loop, giving nine things. range()
also supports the ability to increment by more than one.
03:13 This call counts from one to less than twenty—that’d be nineteen—giving every second number. Okay, let me just create another list here.
03:28 The set object is a sequence that only allows one instance of each thing inside of it.
03:38
Calling it with numbers removes the duplicates, and I’m sure you’ll guess what I’ll do next. Yup. Length of three. A set can be initialized directly using curly brackets ({}
).
03:51 This can be a bit confusing if you’re not used to it. Curly brackets with a sequence inside of it becomes a set. Curly brackets with key value pairs inside become a dictionary.
04:02
So if I take the len()
of an empty set, like you might expect, it has a length of zero. Speaking of dictionaries, let me create one. This reminds me of a childhood toy, the See ‘n Say.
04:17
The cat
says meow
, The dog
says woof
. The person
says a wop ba ba loo bop a wop bam boom
!
04:29
And calling len()
on the dictionary returns three. One for each key in the collection. There are some data types that you can’t call length on, though.
04:41 Length of an integer doesn’t make sense, and Python tells you so. No luck with floats or Booleans or complex numbers. Remember my numbers list? Let’s use that to create an iterator.
05:05
Iterators are a way of incrementally getting at information inside of a collection. If you used numbers in a for
loop, Python would create an iterator out of the list for you automatically in the background. Here’s what an iterator looks like.
05:22
It’s just a reference. You get at the items in an iterator by calling the built-in function next()
on it. In this case, next()
results in the first item in the list. Let’s do something funky.
05:37
This only works in Python 3.8 or newer, but don’t worry if you’re on something earlier. You can just skip this step. Python 3.8 introduced the walrus operator. That’s :=
(colon equal) to its friends.
05:48 This allows you to do assignment and get the value of the assignment at the same time.
05:58
this while
loop calls next()
on the iterator and returns it into value. I’ll put a print()
inside of the while
loop, and this while
loop will keep running, calling next()
on the iterator, getting a value, and keep going until there’s nothing left in the iterator.
06:15
Let’s give it a shot. It iterated over everything until the iterator ran out. When the iterator runs out, it throws a StopIteration
exception, and as I didn’t catch that, that interrupts the flow. That’s okay.
06:31
I was done anyways. Seeing as this is a course on len()
, let me recreate the iterator and do the obvious.
06:46
Yep. Well, that didn’t really work. That was a bit of a long walk to get the failure. Iterators and their cousins, generators, can have unpredictable lengths. As such, you can’t get their length with the len()
function.
06:59 If you truly want the length of something in an iterator, you can convert it to a list, but understand that that is actually iterating through the iterator and taking up all the memory with the result in the list.
07:11
You can then get the length of the list. Well, that’s the basics. Next up. I’ll show you some common coding patterns with len()
.
Geir Arne Hjelle RP Team on Feb. 6, 2022
@Anurag You can think of a “container like object” as something that contains other objects. Typical examples are lists, sets, tuples, and dictionaries. Strings are also “container like”, although they are a bit different from the other examples. You can think of strings as containing their substrings or individual characters.
Anurag Gupta on Feb. 6, 2022
Then can we say that Numbers are also conatiners because they contain individual numbers? But we know that they are not.
Geir Arne Hjelle RP Team on Feb. 6, 2022
@Anurag You can say that numbers contain individual digits, but the Python core developers have chosen not to make numbers containers. You’re making a good point though: which objects that behave “container like” come down to implementation and choice. Picking out digits of numbers were not found to be useful enough for regular Python numbers.
As Christopher explains later in this course, whether you can use len()
on some object comes down to whether the object has defined a .__len__()
method. You can see an extreme version of this in this Hobbit example.
These double-underscore (dunder) methods are special, and make up what’s called the Python’s data model. Essentially, most features in the language are calling such dunder methods and thereby allow your own classes to behave as if they’re native Python classes. You can for instance implement .__getitem__()
to allow slicing and .__contains__()
to allow membership tests with in
.
The Python Documentation details all the possibilities. Luciano Ramalho’s book Fluent Python has my favorite exploration of Python’s data model. You can find examples that use the data model in several articles here on Real Python, including in our Mandelbrot tutorial.
Bartosz Zaczyński RP Team on Feb. 7, 2022
@Anurag Gupta Another way to put it is that containers allow you to, well, contain values at runtime. The key part is the runtime here. On the other hand, numbers are scalar values that don’t offer any storage capabilities. You can’t store anything in a number, but you can in a list or a set.
Christopher Trudeau RP Team on Feb. 7, 2022
The phrase “container-like object” is vague, and my intent wasn’t to be misleading. It isn’t a computer science term, but my attempt at being general. To be more specific might have been more confusing. The strict definition (as Geir Arne) pointed out would be:
len()
works on anything that defines the__len__()
method.
That kind of seems circular, and unless you’re getting into the details of writing your own, not very helpful.
Lists, dictionaries, tuples, strings, and other data types in Python implement len()
and contain other things. In the case of lists and dictionaries, being a container is part of their purpose. In the case of strings it is a bit less obvious as you don’t have to think of them of as a container of characters.
The distinction with numbers is that they don’t implement len()
and can’t be considered a container of digits. This boils down to how everything is stored in memory underneath and is somewhat connected to how data types are thought about in programming languages that precede Python.
You could write a class that extends an integer and implements __len__()
with the response being the digits, but the standard library doesn’t do this.
If all this is too messy, don’t worry about it too much. “Container-like” isn’t a specific programming concept, merely my attempt at generalizing a common idea behind the different things that implement __len__()
.
Become a Member to join the conversation.
Anurag Gupta on Feb. 6, 2022
Can you please redefine the term ‘Container like objects’? I mean, how do we know that a given object is a container type and other is not?