Slicing and Splicing in JavaScript and Python

This post covers some of the syntax and parameters for doing array or list slices and splices in Python and JavaScript — in other words, working with sections of lists or arrays, instead of the whole list/array — and some of the similarities and differences between them.  This is intended as a map between the two languages, rather than a comparison of their strengths and weaknesses.

JavaScript arrays and Python Lists

Lists in Python and arrays in JavaScript are built-in data structures that are used for mostly equivalent things.  They’re both loosely typed sequences of items, indexed by sequential integers starting at 0, with the ability to add or remove items at any point (in other words, they’re not a fixed length).

The differences between the structures they allow, such as that JavaScript arrays can be sparse, while Python’s lists don’t allow this, are beyond the scope of this post.  As we’ll see, there are some differences in the syntax used for splicing and splicing, but also a lot of similarities in how slicing and splicing work in the two languages.

Slicing and Splicing

A slice is a section of an array or list.  Usually it’s a contiguous section (but see the step parameter for an exception to that rule).  When you use the syntax or method calls provided by the language to get a slice of an array, it’s basically a new array or list that’s shallow copy of that section of the original array/list.

Splicing is inserting a sequence of items in an array or list, possibly replacing a given section (i.e. replacing a slice), but possibly just inserting them between existing items.

For both of these features, JavaScript uses built-in methods of the Array class, while Python uses special syntax.

The same slicing syntax works in the same way for strings in both languages, but splicing doesn’t: both languages treat strings as immutable.

Slice Syntax in Python

In Python, to get a slice of a list, you use the following syntax: arrayName[start:stop:step].  Say it with me now: “start stop step”.  I find that the alliteration makes this easy to remember this way, and slice syntax also uses the same parameters as Python’s range() function.

start: The index of the first item to include in the slice.

stop: The index of the first item to *not* include in the slice.

step: The number of items from one included item to the next.  This defaults to 1.  If it’s 2, you’re taking every other item.

Here’s an example:

>> arr = ["red", "green", "blue", "alpha"]
>>> print(arr[1:3:1])
['green', 'blue']

We start with item 1 (remember, lists are zero-based), and stop right before item 3.  So our slice includes items 1 (“green”) and 2 (“blue”).

Since we’re using a step of 1, we can omit that parameter:

>> arr = ["red", "green", "blue", "alpha"]
>>> print(arr[1:3])
['green', 'blue']

The slice() Method in JavaScript

To get a slice of an array, you use the slice() method.  It uses start and end parameters, which function the same as start and stop in Python slices:

>> let arr = ["red", "green", "blue", "alpha"]
>> arr
Array(4) [ "red", "green", "blue", "alpha" ]
>> arr.slice(1, 3)
Array [ "green", "blue" ]

Splicing in Python

As with slices, splicing in Python is done with special syntax.  It’s the same syntax as slices, except you add = afterward to replace the slice with a new sequence:

>>> arr
['red', 'green', 'blue', 'alpha']
>>> arr[1:3] = ["orange", "yellow", "cyan"]
>>> arr
['red', 'orange', 'yellow', 'cyan', 'alpha']

A Python programmer might not usually use the term “splicing”, since there’s no splice() method.  The official Python documentation just calls it “assigning to a slice”.

The splice() method in JavaScript

In JavaScript you splice by calling the array’s splice() method.  This method has a start parameter, which works the same as for slicing.  However, instead of an end parameter it uses deleteCount: the number of items to remove.  The remaining parameters are the items to insert in place of what was removed (and there can be any number of these).

>> let arr = ["red", "yellow", "blue"]
>> arr.splice(1, 1, "green", "orange")
Array [ "yellow" ]  // splice() returns a sequence of the removed items.
>> arr
Array(4)[ "red", "green", "orange", "blue" ]

You can also insert the elements of an array into another array using the spread () operator (similar to * in Python):

>> let arr = [8, 6, 0, 9]
>> let arr2 = [7, 5, 3]
>> arr.splice(2, 0, ...arr2)
Array []
>> arr
Array(7) [ 8, 6, 7, 5, 3, 0, 9 ]

Deleting Ranges

In Python you can delete a range within a list by assigning an empty list to a slice.

>>> arr = ['red', 'orange', 'yellow', 'cyan', 'alpha']
>>> arr[1:4] = []
>>> arr
['red', 'alpha']

You can also use the del keyword:

>>> arr = ['red', 'orange', 'yellow', 'cyan', 'alpha']
>>> del arr[1:4]
>>> arr
['red', 'alpha']

In JavaScript, you remove a range by leaving off the item parameters in the call to splice().

>> arr
Array(4)[ "red", "green", "orange", "blue" ]
>> arr.splice(0, 2) 
Array [ "red", "green" ]
>> arr
Array [ "orange", "blue" ]

Clearing Arrays and Lists

This a bit of a digression, but I decided to look into JavaScript’s slicing/splicing behavior after I learned about splicing being one of the recommended ways to clear an array in JavaScript.

In Python, you can clear a list with just arr.clear(), but there’s no such method in JavaScript.

The most succinct way to empty out a JS array is:

arr.length = 0

But you can also use the splice method:

arr.splice(0, arr.length)

This replaces a section of the array beginning at the beginning, ending at the end, with nothing, since no additional items are provided.

You can do something equivalent in Python as well, using its splice syntax:

arr[:] = []

In most of these cases, adding a comment would probably be helpful, as it’s not immediately clear that emptying out the array is the intent.

The Step Parameter

The step parameter has an additional use, in that, when it’s negative, the slice goes in reverse.

When using the step parameter for splicing, there are some instances where it won’t work, like replacing one slice with a slice of a different size (including an empty one):

>> arr = list(range(10))
>>> arr
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> arr[1::2] = []
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: attempt to assign sequence of size 0 to extended slice of size 5

But you can use del to remove such a slice, even when the step parameter is used:

>> arr
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> del arr[1::2]
>>> arr
[0, 2, 4, 6, 8]

JavaScript’s slice and splice methods do not have a step parameter.

Negative Indices

Negative indices used in the start and stop parameter are essentially aliases for the positive indices.  For example, if the index is -1, it means the item at length – 1.

Python:

>>> arr
[1, 2, 3, 4, 5]
>>> arr[2:4]
[3, 4]
>>> arr[-3:-1]
[3, 4]

Beware that using a negative step parameter means it will start *after* the index specified by the start parameter and stop *before* the index specified by the stop parameter.

>>> arr
[1, 2, 3, 4, 5]
>>> arr[-1:-3:-1]
[5, 4]

For splicing in Python, negative indices work the same as with slicing.

JavaScript:

>> arr
Array(5) [ 1, 2, 3, 4, 5 ]
>> arr.slice(2, 4)
Array [ 3, 4 ]
>> arr.slice(-3, -1)
Array [ 3, 4 ]

When splicing in JavaScript, negative values for the start parameter works the same as with slicing, but negative values for the deleteCount parameter are treated as 0:

>> arr
Array(5) [ 1, 2, 3, 4, 5 ]
>> arr.splice(-1, -1, 4.5)
Array []
>> arr
Array(6) [ 1, 2, 3, 4, 4.5, 5 ]
>> arr.splice(-1, 0, 4.75)
Array []
>> arr
Array(7) [ 1, 2, 3, 4, 4.5, 4.75, 5 ]

Further Reading