# Array slicing notation to get N elements from index I

**URL:** <https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159>\
**Category:** Ideas\
**Created:** [April 24, 2023, 3:16pm UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159 "2023-04-24T15:16:25Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![awjlogan](https://avatars.discourse-cdn.com/v4/letter/a/9e8a1a/32.png) [@awjlogan](https://discuss.python.org/u/awjlogan)\
**Post date:** [April 24, 2023, 3:16pm UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/1 "2023-04-24T15:16:25Z")

</div>

Hi - my first post here 🙂 I’ve had a search through PEPs, forums, and at work but haven’t been able to prove the negative that this syntactic sugar doesn’t exist.

Frequently I need to get an array slice in the form:

`arr[start_idx:(start_idx + some_length)]`

The repetition of the `start_idx` variable and the variable `some_length` seem a bit awkward and ends up with some bracket noise at the end of the statement. For the same transformation, SystemVerilog has the following syntax:

`arr[start_idx +: some_length]`

In the form of the question title, this would be : `arr[I +: N]`

(for completeness, SV has the `-:` operator to give the reversed slice). This seems to me to be a concise method of doing this operation. Others at work came up with the following Python solution:

`arr[start:][:some_length]`

which is nice, but I think this creates a copy of the array first, which might not be desirable and also the `:][:` might not be obvious on scanning this.

It is _very_ unusual that SystemVerilog has nicer syntax than something like Python, so wondered if anyone had any thoughts they’d like to share on this? Hope this is of interest.

---

<div class="post-metadata">

**Author:** ![gkb](https://avatars.discourse-cdn.com/v4/letter/g/6f9a4e/32.png) [@gkb](https://discuss.python.org/u/gkb)\
**Post date:** [April 24, 2023, 6:28pm UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/2 "2023-04-24T18:28:41Z")

</div>

You could solve this with a helper function:

```python
def sl(i, l):
    return slice(i, i+l)

print("abcdefghijk"[sl(3,4)])
# prints defg

```

---

<div class="post-metadata">

**Author:** ![awjlogan](https://avatars.discourse-cdn.com/v4/letter/a/9e8a1a/32.png) [@awjlogan](https://discuss.python.org/u/awjlogan)\
**Post date:** [April 24, 2023, 7:36pm UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/3 "2023-04-24T19:36:04Z")

</div>

Agreed, thanks 🙂 - but that’s a helper function that has to be declared in every project that uses it. Further, and I think more importantly, it is not obvious looking at the usage _what_ it is actually doing - reading it means another redirection to see what `sl` is doing.

---

<div class="post-metadata">

**Author:** ![pf\_moore](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pf_moore/32/35_2.png) [@pf\_moore](https://discuss.python.org/u/pf_moore)\
**Post date:** [April 24, 2023, 7:48pm UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/4 "2023-04-24T19:48:46Z")

</div>

It’s no less obvious than `n+:i`. Quite the opposite - just because the “short” name `sl` is unhelpful, doesn’t mean you can’t find a better name.

And “you have to add the function to each project”. Well, yes, but it’s a one-liner, and as has been said many times, “not every three-line function deserves to be a builtin”. Much less, syntax.

---

<div class="post-metadata">

**Author:** ![abessman](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/abessman/32/8367_2.png) [@abessman](https://discuss.python.org/u/abessman)\
**Post date:** [April 24, 2023, 8:17pm UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/5 "2023-04-24T20:17:12Z")

</div>

+1. `[start : start + n]` is not very DRY.

> [@pf\_moore](#):
>
> It’s no less obvious than `n+:i`.

Having had no prior exposure to the proposed syntax, I find `n+:i` to be quite intuitive, via analogy with `+=`.

> [@pf\_moore](#):
>
> “not every three-line function deserves to be a builtin”. Much less, syntax.

Perhaps a good fit for `itertools`, then?

---

<div class="post-metadata">

**Author:** ![Rosuav](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/rosuav/32/3429_2.png) [@Rosuav](https://discuss.python.org/u/Rosuav)\
**Post date:** [April 24, 2023, 9:34pm UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/6 "2023-04-24T21:34:52Z")

</div>

> [@abessman](#):
>
> > [@pf\_moore](#):
> >
> > “not every three-line function deserves to be a builtin”. Much less, syntax.
> 
> Perhaps a good fit for `itertools`, then?

It’s not really an itertools thing, but you can have your own personal library with whatever you want in it. I usually give mine a really boring name like “utils” or, if I’m feeling really namespacey that day, something derived from my own name (“rosutils” or something).

---

<div class="post-metadata">

**Author:** ![chepner](https://avatars.discourse-cdn.com/v4/letter/c/22d042/32.png) [@chepner](https://discuss.python.org/u/chepner)\
**Post date:** [April 24, 2023, 9:50pm UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/7 "2023-04-24T21:50:38Z")

</div>

> [@awjlogan](#):
>
> Frequently I need to get an array slice in the form:
> 
> `arr[start_idx:(start_idx + some_length)]`
> 
> The repetition of the `start_idx` variable and the variable `some_length` seem a bit awkward and ends up with some bracket noise at the end of the statement.

For what it’s worth, the parentheses aren’t necessary. The colon is part of the slice syntax, not an operator with a higher precedence than `+`.

`arr[start_idx:start_idx + some_length]`

---

<div class="post-metadata">

**Author:** ![Stefan2](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/stefan2/32/18492_2.png) [@Stefan2](https://discuss.python.org/u/Stefan2)\
**Post date:** [April 25, 2023, 1:10am UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/8 "2023-04-25T01:10:04Z")

</div>

And [PEP 8](https://peps.python.org/pep-0008/#whitespace-in-expressions-and-statements) asks for treating the colon like an operator with the lowest priority and prefers spaces accordingly:

```python
# Wrong:
arr[start_idx:start_idx + some_length]

```

```python
# Correct:
arr[start_idx : start_idx+some_length]
arr[start_idx : start_idx + some_length]

```

---

<div class="post-metadata">

**Author:** ![ajoino](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ajoino/32/6907_2.png) [@ajoino](https://discuss.python.org/u/ajoino)\
**Post date:** [April 25, 2023, 6:58am UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/9 "2023-04-25T06:58:24Z")

</div>

I’ve seen a lot of DRY being mentioned here recently, often over small things like this. I thought DRY was mostly about not repeating large chunks of code because it makes it easier to maintain, not about removing every single token that is arbritrarily close to the same token. If being DRY is your thing, APL might be a better fit than Python 😛

---

<div class="post-metadata">

**Author:** ![abessman](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/abessman/32/8367_2.png) [@abessman](https://discuss.python.org/u/abessman)\
**Post date:** [April 25, 2023, 9:42am UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/10 "2023-04-25T09:42:07Z")

</div>

There are degrees to everything. `[start : start + n]` is not sopping wet, but still less dry than `[start+:n]`. `myvar = myvar + 1` is perfectly fine, but I think most people still prefer `myvar += 1`.

Really, the case for `+:` is the same as the case for `+=`. What arguments are there for the existence of `+=` that do not apply to `+:`?

---

<div class="post-metadata">

**Author:** ![ajoino](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ajoino/32/6907_2.png) [@ajoino](https://discuss.python.org/u/ajoino)\
**Post date:** [April 25, 2023, 10:11am UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/11 "2023-04-25T10:11:24Z")

</div>

I don’t know, DRY to me seems like a mantra that doesn’t really help. I think the current way of stating this is crystal clear and requires no explanation beyond how slices work. That to me is much more important than saving 10-ish characters, which you can do with a trivial convenience function as stated above. Even if you have rewrite it in all the libraries you use, the cost is minimal.

---

<div class="post-metadata">

**Author:** ![oscarbenjamin](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/oscarbenjamin/32/1209_2.png) [@oscarbenjamin](https://discuss.python.org/u/oscarbenjamin)\
**Post date:** [April 25, 2023, 10:33am UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/12 "2023-04-25T10:33:22Z")

</div>

> [@abessman](#):
>
> Really, the case for `+:` is the same as the case for `+=`. What arguments are there for the existence of `+=` that do not apply to `+:`?

The fact that `+=` is a much more common operation is an argument for considering these differently. It is good to have terse syntax for things that are used a lot and that programmers are likely to become familiar with early on. The use of `+=` for in-place addition is also very prevalent in other languages so many programmers coming to Python from other languages are likely to understand approximately what it means immediately.

The `+=` operator naturally generalises to all binary operators `-=`, `*=`, `&=` etc and so a single syntactic construct can be learned that has many possible applications. If we allow `+:` then immediately the question will be what about `-:`, `&:` etc but the usefulness of the syntax does not extend to these cases.

---

<div class="post-metadata">

**Author:** ![Rosuav](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/rosuav/32/3429_2.png) [@Rosuav](https://discuss.python.org/u/Rosuav)\
**Post date:** [April 25, 2023, 10:35am UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/13 "2023-04-25T10:35:13Z")

</div>

> [@abessman](#):
>
> Really, the case for `+:` is the same as the case for `+=`. What arguments are there for the existence of `+=` that do not apply to `+:`?

Frequency of use, mainly 🙂 Incrementing a number or extending a sequence is extremely common, but this kind of slicing isn’t nearly as much so.

Another argument to consider is how frequently you’d want to do this with something that isn’t just a simple variable. When you do something like `stuff["whatever"].value[3] += 1` the majority of the left hand side is only evaluated once. That’s certainly possible with the proposed syntax, but I’m not sure how often it’d happen.

---

<div class="post-metadata">

**Author:** ![awjlogan](https://avatars.discourse-cdn.com/v4/letter/a/9e8a1a/32.png) [@awjlogan](https://discuss.python.org/u/awjlogan)\
**Post date:** [April 25, 2023, 10:36am UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/14 "2023-04-25T10:36:23Z")

</div>

I didn’t _really_ present this from a DRY perspective (which I take, as Jacob said, to be more like large chunks of code) - more that the repetition of the starting index makes (possibly subjectively) the interpretation harder: longer statement, need to mentally check what the repeated variable means, and the potential bracket noise to make clear the intent of the precedence (Stefan’s pointer to PEP8 is interesting, although I don’t _remember_ a linter picking that one up).

The analogy to `+=` I think is the most relevant one here - that is a shorthand for a common operation and both the intent and result are immediately obvious (no need to reparse the repeated variable name). The helper function with `slice` adds another level of indirection to determine what the index boundaries are - given how many logical errors come from index bounds, anything that makes the bounds and/or range easier to determine is helpful to the user.

---

<div class="post-metadata">

**Author:** ![awjlogan](https://avatars.discourse-cdn.com/v4/letter/a/9e8a1a/32.png) [@awjlogan](https://discuss.python.org/u/awjlogan)\
**Post date:** [April 25, 2023, 10:40am UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/15 "2023-04-25T10:40:51Z")

</div>

> The `+=` operator naturally generalises to all binary operators `-=`, `*=`, `&=` etc and so a single syntactic construct can be learned that has many possible applications. If we allow `+:` then immediately the question will be what about `-:`, `&:` etc but the usefulness of the syntax does not extend to these cases.

This is a fair point 🙂 `-:` does have meaning in SystemVerilog (reverses the order of the _N_ elements starting from index _I_), but that isn’t immediately obvious (I don’t think, at least).

---

<div class="post-metadata">

**Author:** ![chepner](https://avatars.discourse-cdn.com/v4/letter/c/22d042/32.png) [@chepner](https://discuss.python.org/u/chepner)\
**Post date:** [April 25, 2023, 10:43am UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/16 "2023-04-25T10:43:45Z")

</div>

> [@abessman](#):
>
> Really, the case for `+:` is the same as the case for `+=`. What arguments are there for the existence of `+=` that do not apply to `+:`?

In-place modification of mutable objects.

---

<div class="post-metadata">

**Author:** ![abessman](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/abessman/32/8367_2.png) [@abessman](https://discuss.python.org/u/abessman)\
**Post date:** [April 25, 2023, 11:14am UTC](https://discuss.python.org/t/array-slicing-notation-to-get-n-elements-from-index-i/26159/17 "2023-04-25T11:14:27Z")

</div>

> [@oscarbenjamin](#):
>
> The `+=` operator naturally generalises to all binary operators `-=`, `*=`, `&=` etc and so a single syntactic construct can be learned that has many possible applications. If we allow `+:` then immediately the question will be what about `-:`, `&:` etc but the usefulness of the syntax does not extend to these cases.

Fair. Although, I would personally _love_ if I could do `slicable_thing[start /: n]` and get n evenly sized chunks of `slicable_thing` 😉 Yes, I realize there are a bunch of cases where that would break down.
