|
25 | 25 | DTYPES_BOOL = (DTYPE_BOOL,) |
26 | 26 | DTYPES_INEXACT = (DTYPE_FLOAT_DEFAULT, DTYPE_COMPLEX_DEFAULT) |
27 | 27 |
|
| 28 | +EMPTY_SLICE = slice(0, 0) # gathers nothing |
| 29 | + |
28 | 30 |
|
29 | 31 | def mloc(array: np.ndarray) -> int: |
30 | 32 | '''Return the memory location of an array. |
@@ -261,5 +263,44 @@ def count_iteration(iterable: tp.Iterable): |
261 | 263 | return count |
262 | 264 |
|
263 | 265 |
|
| 266 | +def slice_to_ascending_slice( |
| 267 | + key: slice, |
| 268 | + size: int |
| 269 | + ) -> slice: |
| 270 | + ''' |
| 271 | + Given a slice, return a slice that, with ascending integers, covers the same values. |
| 272 | +
|
| 273 | + Args: |
| 274 | + size: the length of the container on this axis |
| 275 | + ''' |
| 276 | + key_step = key.step |
| 277 | + key_start = key.start |
| 278 | + key_stop = key.stop |
| 279 | + |
| 280 | + if key_step is None or key_step > 0: |
| 281 | + return key |
| 282 | + |
| 283 | + # will get rid of all negative values greater than the size; but will replace None with an appropriate number for usage in range |
| 284 | + norm_key_start, norm_key_stop, norm_key_step = key.indices(size) |
| 285 | + |
| 286 | + # everything else should be descending, but we might have non-descending start, stop |
| 287 | + if key_start is not None and key_stop is not None: |
| 288 | + if norm_key_start <= norm_key_stop: # an ascending range |
| 289 | + return EMPTY_SLICE |
| 290 | + |
| 291 | + norm_range = range(norm_key_start, norm_key_stop, norm_key_step) |
| 292 | + |
| 293 | + # derive stop |
| 294 | + if key_start is None: |
| 295 | + stop = None |
| 296 | + else: |
| 297 | + stop = norm_range[0] + 1 |
| 298 | + |
| 299 | + if key_step == -1: |
| 300 | + # gets last realized value, not last range value |
| 301 | + return slice(None if key_stop is None else norm_range[-1], stop, 1) |
| 302 | + |
| 303 | + return slice(norm_range[-1], stop, key_step * -1) |
| 304 | + |
264 | 305 |
|
265 | 306 |
|
0 commit comments