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 sliceable?
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.
- Build Games for Python Using Pygame | What is PyGame? | Basic PyGame Program
- Python Programming – Python Single Inheritance
- Python Programming – The Class Program
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.