Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve length of slice from slice object in Python

Tags:

The title explains itself, how to get 2 out of the object

slice(0,2) 

The documentation is somewhat confusing, or it is the wrong one

https://docs.python.org/2/c-api/slice.html

In particular I don't understand what is the meaning of the output of

slice(0,2).indices(0)  # (0, 0, 1) slice(0,2).indices(10 ** 10)  # (0, 2, 1) 

One possible workaround is to slice a list with the slice object

a = [1,2,3,4,5] len(a[slice(0,2)])  # 2 

But this will fail for an arbitrary large slice.

Thanks, I couldn't find an answer In other posts.

like image 218
latorrefabian Avatar asked Mar 23 '16 20:03

latorrefabian


People also ask

What does the slice () object return?

The slice() function returns a slice object. A slice object is used to specify how to slice a sequence. You can specify where to start the slicing, and where to end. You can also specify the step, which allows you to e.g. slice only every other item.

How do you read a slice in Python?

Basic Usage of Slices The full slice syntax is: start:stop:step. start refers to the index of the element which is used as a start of our slice. stop refers to the index of the element we should stop just before to finish our slice. step allows you to take each nth-element within a start:stop range.

What is :: In slicing?

Consider a python list, In-order to access a range of elements in a list, you need to slice a list. One way to do this is to use the simple slicing operator i.e. colon(:) With this operator, one can specify where to start the slicing, where to end, and specify the step.

When slicing in Python What does the 2 in [:: 2 specify?

Second note, when no start is defined as in A[:2] , it defaults to 0. There are two ends to the list: the beginning where index=0 (the first element) and the end where index=highest value (the last element).


1 Answers

There is no complete answer for this. slice doesn't give you a length because the length of the result is always dependent on the size of the sequence being sliced, a short sequence (including an empty sequence) will produce fewer items, and if the slice is unbounded, then the length will grow in tandem with the length of the sequence; a slice might just go "to end of sequence" by having a start or stop of None.

For a quick and easy way to compute the length for a sequence of a known length, you just combine .indices with Py3's range (or xrange in Py2, though xrange has limitations on values that Py3 range does not). slice.indices gives you the concrete start, stop and stride values derived when a slice applies to a sequence of a given length, it's basically the values you'd fill in in a C-style for loop that traverses the same indices as the slice:

 for (ssize_t i = start; i < stop; i += stride) 

So to calculate the length of a slice when applied to a sequence with 1000 elements, you'd do:

>>> len(range(*slice(0, 2).indices(1000))) 2 >>> len(range(*slice(10, None, 3).indices(1000))) 330 

If you're on Python 2, and your values might exceed what xrange can handle (it's limited to bounds and total length equal to what a ssize_t can hold), you can just do the calculation by hand:

def slice_len_for(slc, seqlen):     start, stop, step = slc.indices(seqlen)     return max(0, (stop - start + (step - (1 if step > 0 else -1))) // step)  >>> slice_len_for(slice(10, None, 3), 1000) 330 

Update: Unfortunately, slice.indices itself won't accept a len for the sequence beyond what a long can hold, so this doesn't gain you anything over using xrange in Py2. Left in place for those interested, but the workaround doesn't workaround anything unless you also perform the work slice does to convert negative values and None to concrete values based on the sequence length. Sigh.

like image 101
ShadowRanger Avatar answered Oct 05 '22 15:10

ShadowRanger