Created
November 24, 2017 18:31
-
-
Save Elizafox/0b9f28e5147da99098ce848ac701bd21 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from itertools import zip_longest | |
class ListSlices: | |
"""A basic template for how to implement slice support for list-like | |
objects. | |
This exploits the fact that the semantics of range() are the same as | |
list slices. | |
""" | |
def __getitem__(self, item, value): | |
if isinstance(item, slice): | |
indices = item.indices(len(self)) | |
return [self[i] for i in range(*indices)] | |
# Non-slice case | |
raise NotImplementedError | |
def __setitem__(self, item, value): | |
if isinstance(item, slice): | |
len_self = len(self) | |
len_value = len(value) | |
indices = item.indices(len_self) | |
# Slice length | |
len_slice = (indices[1] - indices[0]) // indices[2] | |
if len_slice > len_value and indices[2] != 1: | |
# Mimicking default Python list behaviour | |
e = ("attempt to assign sequence of size {} to extended " | |
"slice of size {}").format(len_value, len_slice) | |
raise ValueError(e) | |
# NOTE: | |
# vi is the index of the unpacked value | |
# v is the value we are unpacking | |
# i is the range of the indicies | |
for (vi, v), i in zip_longest(enumerate(value), range(*indices)): | |
if i is None: | |
# i will be None if the range is exhausted before we run | |
# out of values to unpack, so make a provision for that. | |
# This mimics Python's default behaviour. | |
i = vi + indices[1] | |
if i >= len_self: | |
# If we're about to exceed array length, append onto | |
# ourselves. If you don't implement an append() operation, | |
# you'll want to change this to something equivalent (or | |
# raise an error). | |
self.append(v) | |
else: | |
self[i] = v | |
return | |
# Non-slice case | |
raise NotImplementedError |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment