"
This article is part of in the series
Published: Thursday 4th April 2013
Last Updated: Wednesday 29th December 2021

For an introduction to slicing, please view the article How to Slice Lists/Arrays and Tuples in Python.

Slicing Your Own Python Objects

Alright, that's all cool, now we know how to slice. But how do we slice our own objects? If I implement an object that has a list, or custom data structure, how do I make it slicable?

First, we define our custom data structure class.

[python]
from collections import Sequence

class MyStructure(Sequence):
def __init__(self):
self.data = []

def __len__(self):
return len(self.data)

def append(self, item):
self.data.append(item)

def remove(self, item):
self.data.remove(item)

def __repr__(self):
return str(self.data)

def __getitem__(self, sliced):
return self.data[sliced]
[/python]

Here, we declare a class with a list as the back-end of our structure. MyStructure doesn't really do that much, but you can add, remove, and get items from it, so it's still useful in a sense. The only method we need to pay attention to in particular here is the __getitem__ method. This method is called whenever we try to get an item from our structure. When we call structure[0], this actually calls the __getitem__ method in the background and returns whatever that method returns. It's very useful when implementing a list style object.

Let's create our custom object, add an item to it, and try to get it.

[python]
>>> m = MyStructure()
>>> m.append('First element')
>>> print(m[0])
First element
[/python]

Yes! We did it! We assigned our element, and properly got it back. Nice. Now for the slicing part!

[python]
>>> m.append('Second element')
>>> m.append('Third element')
>>> m
['First element', 'Second element', 'Third element']
>>> m[1:3]
['Second element', 'Third element']
[/python]

Awesome! We basically get all the slicing for free because of using list's functionality.

That's pretty amazing. Python is amazing. How about something a little more complex? What about using a dictionary as our main data structure?

Alright. Let's define another class for using a dictionary.

[python]
class MyDictStructure(Sequence):
def __init__(self):
# New dictionary this time
self.data = {}

def __len__(self):
return len(self.data)

def append(self, item):
self.data[len(self)] = item

def remove(self, item):
if item in self.data.values():
del self.data[item]

def __repr__(self):
return str(self.data)

def __getitem__(self, sliced):
slicedkeys = self.data.keys()[sliced]
data = {k: self.data[k] for key in slicedkeys}
return data
[/python]

Ok, so what are we doing here? Basically the same stuff that we did in the MyStructure, but this time we're using a dictionary as our main structure, and the __getitem__ method definition has changed. Let me explain what changed in __getitem__.

First, we get the slice object that is passed in to __getitem__ and use it to slice the dictionary's key values. Then, using dictionary comprehension, we put all of the sliced keys and values into a new dictionary using our sliced keys. This gives us a nice sliced dictionary that we can use for whatever we like.

Here it is in action:

[python]
>>> m = MyDictStructure()
>>> m.append('First element')
>>> m.append('Second element')
>>> m.append('Third element')
>>> m
{0: 'First element', 1: 'Second element', 2: 'Third element'}
>>> # slicing
>>> m[1:3]
{1: 'Second element', 2: 'Third element'}
[/python]

And that's it. Simple, elegant, and powerful.

If you want to know how to slice strings, that's covered in another article titled How to Get a Sub-string From a String in Python – Slicing Strings.

That's all for now. Hope you enjoyed learning about slicing and I hope it will assist you in your quest.

Peace out.

About The Author

Joey Payne