37

The Python tutorial explains slice behavior when indices are negative, but I can't find documentation describing the behavior when the end index precedes the start index. (I've also looked at Explain Python's slice notation, and perhaps I'm not reading carefully enough, but the answers there don't seem to address this point.)

The behavior that I observe is that an empty list is returned, which seems reasonable to me. However, it also would seem reasonable to me for this to return a list of items between i and j in reversed order or to simply raise an exception.

Is list[i:j] guaranteed to be an empty list if list[j] precedes list[i]?

Community
  • 1
  • 1
jamesdlin
  • 81,374
  • 13
  • 159
  • 204

1 Answers1

44

Yes, if j <= i is true, the resulting slice is empty, for standard Python types. To get the results in reverse order, you need to add a negative stride:

list[i:j:-1]

because explicit is better than implicit.

This is documented in Common Sequence Operations, footnote 4:

The slice of s from i to j is defined as the sequence of items with index k such that i <= k < j. If i or j is greater than len(s), use len(s). If i is omitted or None, use 0. If j is omitted or None, use len(s). If i is greater than or equal to j, the slice is empty.

Bold emphasis mine.

Custom types are free to interpret this differently.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    Ah, *that's* where it's mentioned in the Python documentation. Exactly what I was looking for. – jamesdlin Jan 22 '15 at 11:01
  • What do you mean with the italic "for standard Python types"? – Stephan Dollberg Jan 22 '15 at 15:27
  • 2
    @bamboon: handling of slices is type specific. The `list`, `tuple`, `str`, `bytes` and `range` types all behave like this, but if you implement your own type your `__getitem__` method is free to handle slices differently. – Martijn Pieters Jan 22 '15 at 15:33
  • @MartijnPieters Ah ok, I thought this question was explicitly about `list`. – Stephan Dollberg Jan 22 '15 at 15:43
  • 2
    @bamboon: and I am pre-emptively heading off comments along the line of *does this apply to strings and tuples too?* and *but project X doesn't behave like that, is that a bug?*. – Martijn Pieters Jan 22 '15 at 15:47
  • @MartijnPieters Yeah yeah, no offense. I was just confused and that's why I asked. – Stephan Dollberg Jan 22 '15 at 16:01
  • BTW, footnote 4 needs the context of footnote 3. The "If *i* is greater than or equal to *j*, the slice is empty." bit isn't true if *j* is negative (and that's why I posed my question with the slightly obtuse "if list[j] precedes list[i]" phrasing rather than "if j < i". – jamesdlin Jan 03 '17 at 12:15
  • @jamesdlin: handling of negative indices is done before the rules of footnote 4 are applied, so `i` and `j` are positive by that point. – Martijn Pieters Jan 03 '17 at 12:19
  • Right, that's the context of footnote 3 that I was referring to. – jamesdlin Jan 03 '17 at 13:01