Skip to main content

Add Mutating Slices to Python

Project description

Slicey


Add Mutating Slices to Python

Mutating slices (or "reference slices") deal with a subset of a list as if it was its own list. This contrasts python's native "value slicing" where slicing a list provides a new list.

Let's Take a Look


Starting with python's normal slicing

base = [0, 1, 2, 3, 4]
slc = base[0:]  # take a slice of the whole list
# now let's check each element is the same in each list
assert all(base[i] == slc[i] for i in range(len(base)))
# if we change the slice (slc) the base won't change
slc[2] = -1
# now they should be different
assert base[2] != slc[2]

However, with slicey you can opt into slices that change the base.

from slicey import Slice

base = [0, 1, 2, 3, 4]
slc = Slice(base)[0:] # slicey slicing syntax
assert all(base[i] == slc[i] for i in range(len(base)))
slc[2] = -1
assert base[2] == slc[2]

Excluding that slicey slices mutate the base list, they can be used like a normal slice!

from slicey import Slice

base = [7, 3, 2, 5, 4]

slc = Slice(base)[1:-1]  # grab from 1 through 3 ([3, 2, 5])
assert [*slc] == [3, 2, 5]

slc[2] = 1
assert base[3] == 1

slc.sort()
assert base == [7, 1, 2, 3, 4]

Why


Don't get me wrong, I love python! But sometimes... you just want a pointer.

The initial inspiration for this project was implementing merge sort, in a clear manner. Often merge sort is written with a variety of indices (i, j, k, etc); I can't speak for other but I can't make heads or tails of it. In languages that expose raw pointers, like c, one can mutate subsections of arrays by referencing an item and passing a smaller length to some function. In short, I wanted to write a merge sort I sould read.

Some Nitty Gritty


Slicing Slicey Slices ... ( ☉︵ ಠ )?

slicey is always opt-in. This means when you slice a slicey slice (an instance of Slice) you'll get an object of whatever slicing the base object would be.

In the likely case that was non-sense, let's just take a look

from slicey import Slice

base = [*range(10)]  # a native list
slc = Slice(base)[1:10]  # a slicey slice
natv_sublc = slc[1:-1]  # a native list equal to base[2:9]
assert type(natv_sublc) == type(base)
assert natv_sublc == base[2:9]

Sometimes it make sense to have a refence slice of a reference slice.

# continuing from above

slcy_subslc = slc.slice[1:-1]  # an instance of Slice
assert type(slcy_subslc) is Slice
assert [*slcy_subslc] == base[2:9]
# for the generic programmers among us Slices can be subsliced like a list
gnrl_slc = Slice(slc)[1:-1]

Transparent Slice Collapsing

Some steps have been taken to avoid indirection when sub-slicing instances of Slice. Taking a sub-slice of a Slice is always equivalent to take a slice out of the base object

readme todo

  • changing base list size not permitted, b/c notifications
  • excluding .pop() and other length mutating methods
  • typing and Sliceable

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

slicey-0.1.0.tar.gz (5.8 kB view hashes)

Uploaded Source

Built Distribution

slicey-0.1.0-py3-none-any.whl (6.4 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page