An Object That Contains Objects • Python's Containers (Data Structure Categories #4)
Containers • Part 4 of the Data Structure Categories Series
Everything in Python is an object. But some objects contain other objects. They're containers.
This won't be a long article. But I'll also talk about another category along the way: sized objects. Yes, they're objects that have a size. Not all terms in programming are weird and complex!
The Data Structure Categories Series
We're on the fourth of seven articles in this series. You can read the previous ones by following the links in this overview:
What's a Container?
A container is an object that contains other objects. So, an integer is not a container. But a list is. So are tuples, dictionaries, sets, and many other data structures. Even strings are containers since they contain individual characters, which are strings of length 1
.
It may be tempting to think that all data structures are containers since they all deal with multiple elements. However, we'll see later in this series that some objects deal with multiple items but are not containers. We'll get to iterators later in this series.
An object is a container if the class has the __contains__()
special method, which defines what "containing" an object means.
The container category is high up in the hierarchy of data structure categories. Many data structures are containers, but they all also have other properties. For example, a list is a container, but it's also iterable and can be indexed.
A class with the __contains__()
special method and little else is not very useful. So why do we need a container category if a container that doesn't do much else is not very useful? Python is a duck typing language. This means we're more concerned about what an object can do rather than what it is. Therefore, when an object is a container, we know it can contain other objects!
I'll write more about the duck typing philosophy in Python in a future article.
You can use the in
keyword to check whether an item is contained within a container. Here are some examples:
Let's test this with a dummy class:
This __contains__()
special method is rather bizarre and not very useful. But it helps us understand how the special method works. The __contains__()
method returns True
if item
is equal to 10
and False
for any other value.
The statement 5 in test_object
is equivalent to test_object.__contains__(5)
, which returns False
. When you check whether test_object
"contains" 10
, the __contains__()
special method returns True
since item
is now 10
.
The ability to use the in
keyword on an object is not a sufficient condition for the object to be a container. Here's an example using zip()
:
This returns True
, and you may be tempted to conclude that the zip
object pairs
is a container and that it contains the tuple ("Albert", "Einstein")
. However, a zip
object is not a container. It's an iterator, and iterators don't contain data. If you're not convinced, see what happens if you check whether the tuple is in the zip
object a second time:
If pairs
"contained" the tuple, both statements should return True
. We'll revisit iterators towards the end of this series on data structure categories.
I have a beginner’s textbook, written in the same relaxed and friendly manner as these articles. Available in paperback and ebook.
And What's a Sized Object?
Here's another category close to the top of the hierarchy of data structure categories: a sized object is one that has a length. You can use the built-in len()
function on a sized object. And the len()
function calls the object's __len__()
special method. Therefore, an object is sized if it has a __len__()
special method.
Here's another dummy class as an example:
An object is sized as long as it has a __len__()
method. In a real case scenario, the __len__()
method works out the actual number of items in the object.
The Hierarchy of Data Structure Categories
Let's look at the chart you've already seen earlier in this series. The categories we discussed today are at the top of the hierarchy, along with iterables. Note that this chart only includes a selection of categories. There are others not shown here!
You can think of these top-level categories as basic building blocks for other data structures. Many data structures you're familiar with, like lists, dictionaries, tuples, and sets, are all iterable, sized containers. In fact, we have another name for structures that fall under all three categories. We'll talk about collections in the next article.
However, as you can see in the chart, not all data types fall under all three. We'll finish this series with iterators and generators, which are iterable but are neither sized nor containers.
Etymology Corner
The term “container” comes from the Latin continere, which means “to hold together” or “to enclose”. The Latin prefix con- means “together”, and the verb tenere is “to hold”.
Next in the series: collection
Code in this article uses Python 3.11
Stop Stack
Recently published articles on The Stack:
Zen and The Art of Python turtle Animations • A Step-by-Step Guide. Python's
turtle
is not just for drawing simple shapesThe One About The Taxi Driver, Mappings, and Sequences • A Short Trip to 42 Python Street. How can London cabbies help us learn about mappings and sequences in Python?
Deconstructing Ideas And Constructing Code • Using the Store-Repeat-Decide-Reuse Concept. Starting to code on a blank page • How do you convert your ideas into code?
There's A Method To The Madness • Defining Methods In Python Classes. Year 3 at Hogwarts School of Codecraft and Algorithmancy • Defining Methods
Finding Your Way To The Right Value • Python's Mappings. Part 3 of the Data Structure Categories Series
Coming soon on The Stack: Another topic I write about from time to time is NumPy. And Matplotlib. So expect some articles about these packages soon.
Most articles will be published in full on the free subscription. However, a lot of effort and time goes into crafting and preparing these articles. If you enjoy the content and find it useful, and if you're in a position to do so, you can become a paid subscriber. In addition to supporting this work, you'll get access to the full archive of articles and some paid-only articles. Thank you!
linke to "Collection" at end of article is not working ("Next in the series: collection")