0

I need to slice array with arbitrary dimensions by two tuples. I can use slicing, such as a[1:3, 4:6]. But what do i do if 1,3 and 4,6 are tuples?

While a[(1, 3)] works, I tried a[(1, 3), (4, 6)] and it didn't work, I think it ignores (4, 6). And I couldn't figure out how to make something like a[ t1[0] : t1[1], t2[0] : t2[1] ] work depending on how many dimensions there are.

I'd like something like a[(1, 3):(4, 6)], that would also work for higher dimensions, e.g a[(1, 3, 2):(4, 6, 5)]

petezurich
  • 9,280
  • 9
  • 43
  • 57
stunlocked
  • 181
  • 10
  • 1
    Try `slice(*tup))`. – Mark Ransom Feb 04 '23 at 14:57
  • @MarkRansom I am not quite sure how to do that. Here is what I did: a[slice( *(1,2) )]. It selected the second row, completely ignoring "2". I also tried a[slice( *((1, 2), (3, 5)) )] and it said TypeError: slice indices must be integers – stunlocked Feb 04 '23 at 15:11
  • If you have `t1 = (1, 3)` and `t2 = (4, 6)`, then `a[1:3, 4:6]` is equivalent to `a[slice(*t1), slice(*t2)]`. – chepner Feb 04 '23 at 15:14
  • Your last example would simply be `a[t1:t2]` for the same tuples. – chepner Feb 04 '23 at 15:14
  • `a[x:y:z]` is, by definition, `a[slice(x, y, z)]`. The `slice` type is how the extended slice syntax is implemented. – chepner Feb 04 '23 at 15:15
  • Is `a[(1, 3, 2):(4, 6, 5)]` supposed to translate to `a[1:3:2, 4:6:5]` or `a[1:4, 3:6, 2:5]`? The key to all answers is that `a[b,c,d]` is actually `a[(b,c,d)]`, where the items in the tuple can be `slice` objects, numbers, or arrays. Create that tuple however you find convenient. – hpaulj Feb 04 '23 at 16:19

1 Answers1

2

Extended slice syntax is implemented by the slice type. You can play with this using a simple toy class

class A:
    def __getitem__(self, k):
        print(k)

Then

>>> A()[1:3, 4:6]
(slice(1, 3, None), slice(4, 6, None))

None is the default 3rd argument if only two are given. So if you have tuples (1, 3) and (4, 6), you can pass explicit slice objects created from them instead of using the extended slicing syntax.

>>> t1, t2 = (1,3), (4, 6)
>>> A()[slice(*t1), slice(*t2)]
(slice(1, 3, None), slice(4, 6, None))
chepner
  • 497,756
  • 71
  • 530
  • 681