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.

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]

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.

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

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

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

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.

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

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:

>>> 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'}

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.

Leave a Reply

Your email address will not be published. Required fields are marked *