Python uses an index of -1 to index the last element in a list. Since -1 occurs before 0 we might think of the elements of the linear list are being bent into a circle making the last element occur before the 0th element. Consider a list with n elements: it would be perfectly reasonable to address the element 0 of the list using an index of n since n occurs after n-1 (if we assume that the list is bent into a circle). This feature can prove to be extremely useful. Consider the following example: days_of_the_week = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"] It would be nice if days_of_the_week[0] is the same as days_of_the_week[7] is the same as days_of_the_week[14] etc In other words use modular indexing. In other words if the index is outside the range 0 to n-1, we simply take the remainder when the index is divided by n as the index. Because of the close relationship between finite length sequences and periodic sequences this feature might simplify scientific computing(circular convolution etc).
November 24, 2020 2:36 PM, "Mathew M. Noel via Python-ideas" <python-ideas@python.org (mailto:python-ideas@python.org?to=%22Mathew%20M.%20Noel%20via%20Python-ideas%22%20<python-ideas@python.org>)> wrote: [snip] This feature can prove to be extremely useful. It can also prove to be extremely dangerous. "list index out of range" errors can often be indicators of a bug elsewhere, and this would cause those bugs to silently pass. --Edwin
I believe this would be simple to implement when it's needed by subclassing `collections.UserList` and wrapping this functionality around `__getitem__`, `__setitem__`, and `__delitem__`. On Tue, Nov 24, 2020, 2:38 PM Mathew M. Noel via Python-ideas < python-ideas@python.org> wrote:
Python uses an index of -1 to index the last element in a list. Since -1 occurs before 0 we might think of the elements of the linear list are being bent into a circle making the last element occur before the 0th element. Consider a list with n elements: it would be perfectly reasonable to address the element 0 of the list using an index of n since n occurs after n-1 (if we assume that the list is bent into a circle). This feature can prove to be extremely useful. Consider the following example:
days_of_the_week = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]
It would be nice if
days_of_the_week[0]
is the same as
days_of_the_week[7]
is the same as
days_of_the_week[14] etc
In other words use modular indexing. In other words if the index is outside the range 0 to n-1, we simply take the remainder when the index is divided by n as the index. Because of the close relationship between finite length sequences and periodic sequences this feature might simplify scientific computing(circular convolution etc).
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/ZEH5W2... Code of Conduct: http://python.org/psf/codeofconduct/
On 11/24/20 2:36 PM, Mathew M. Noel via Python-ideas wrote:
Python uses an index of -1 to index the last element in a list. Since -1 occurs before 0 we might think of the elements of the linear list are being bent into a circle making the last element occur before the 0th element. Consider a list with n elements: it would be perfectly reasonable to address the element 0 of the list using an index of n since n occurs after n-1 (if we assume that the list is bent into a circle). This feature can prove to be extremely useful. Consider the following example:
days_of_the_week = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"] It would be nice if days_of_the_week[0] is the same as days_of_the_week[7] is the same as days_of_the_week[14] etc In other words use modular indexing. In other words if the index is outside the range 0 to n-1, we simply take the remainder when the index is divided by n as the index. Because of the close relationship between finite length sequences and periodic sequences this feature might simplify scientific computing(circular convolution etc).
If I wanted this sort of indexing, using % works very well. Losing the error detection of out of bounds indexing would be very bad in most cases. As I think about this, the only cases that I would likely do this will have a fixed sized list (like the 7 days of the week) it makes it fairly trivial. -- Richard Damon
Hello, On Tue, 24 Nov 2020 19:36:03 +0000 "Mathew M. Noel via Python-ideas" <python-ideas@python.org> wrote:
Python uses an index of -1 to index the last element in a list. Since -1 occurs before 0 we might think of the elements of the linear list are being bent into a circle making the last element occur before the 0th element. Consider a list with n elements: it would be perfectly reasonable to address the element 0 of the list using an index of n since n occurs after n-1 (if we assume that the list is bent into a circle). This feature can prove to be extremely useful.
No.
Consider the following example:
days_of_the_week = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]
It would be nice if
days_of_the_week[0]
is the same as
days_of_the_week[7]
is the same as
days_of_the_week[14] etc
In other words use modular indexing.
If you want to use modular indexing, do exactly that: days_of_the_week[7 % 7] days_of_the_week[14 % 7] days_of_the_week[foo % 7] As was already mentioned, you can even hide that behind a 'list' subclass. -- Best regards, Paul mailto:pmiscml@gmail.com
On 26/11/20 2:30 am, nathan.w.edwards@outlook.com wrote:
At times I heavily rely on index out of bound exceptions to reduce the number of lines necessary for error checking.
This is a downside to the negative indexing scheme -- you can't tell the difference between a backwards index and an error due to out-of-bounds indexing. Making all indexing circular would just make this problem heaps worse. I would have preferred a different syntax for backwards indexing instead of inferring it from the index value, but we're stuck with it now. -- Greg
On Thu, Nov 26, 2020 at 12:07:56PM +1300, Greg Ewing wrote:
On 26/11/20 2:30 am, nathan.w.edwards@outlook.com wrote:
At times I heavily rely on index out of bound exceptions to reduce the number of lines necessary for error checking.
This is a downside to the negative indexing scheme -- you can't tell the difference between a backwards index and an error due to out-of-bounds indexing.
Sorry, perhaps I am being a bit dim-witted this morning, but I don't understand this. Surely the difference is obvious? a = "abcdef" a[-2] # returns a result a[999] # raises an exception Obviously you can tell the two apart, so I'm confused by your comment. Valid indices are the half-open interval `-n <= index < n` where n is the length of the sequence. Outside of that interval, you get an exception. -- Steve
On Wed, Nov 25, 2020 at 3:44 PM Steven D'Aprano <steve@pearwood.info> wrote:
Obviously you can tell the two apart, so I'm confused by your comment.
What I imagined while reading Greg's comment was trying to explain to a student why this didn't work the way they expected. "Ok, so in the first case I'm *not* starting at the beginning? I'm starting in the *middle??? *That makes no sense." forward = False data = [1, 2, 3, 4] if forward: # Start at the beginning and count up. idx = 0 step = 1 else: # Start at the end and count down. idx = len(data) - 1 step = -1 while True: try: print(data[idx]) except IndexError: break else: idx += step
On 11/25/2020 6:41 PM, Steven D'Aprano wrote:
On Thu, Nov 26, 2020 at 12:07:56PM +1300, Greg Ewing wrote:
On 26/11/20 2:30 am, nathan.w.edwards@outlook.com wrote:
At times I heavily rely on index out of bound exceptions to reduce the number of lines necessary for error checking. This is a downside to the negative indexing scheme -- you can't tell the difference between a backwards index and an error due to out-of-bounds indexing. Sorry, perhaps I am being a bit dim-witted this morning, but I don't understand this. Surely the difference is obvious?
a = "abcdef" a[-2] # returns a result a[999] # raises an exception
Obviously you can tell the two apart, so I'm confused by your comment.
If they're literals, it's easy. But a[an_index-an_offset] isn't so easy to spot, say if you're using the wrong offset for example. In other programming languages, it might be an error for the index to be negative. In Python it's not, if the result <= -length(a). Sure, you could use an assert, but many people won't, and the assert can be optimized away. I've been burned by this a number of times. Eric
Hello, On Thu, 26 Nov 2020 13:27:46 +1300 Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
On 26/11/20 12:41 pm, Steven D'Aprano wrote:
a = "abcdef" a[-2] # returns a result
Yes, but did you *intend* that result, or did the -2 result from a calculation that should have returned a positive index but went wrong? Python has no way to tell.
Certainly it does: idx = index_calc() assert idx >= 0 Compare that with the case where index of 5 is invalid (just can't happen per algorithm invariants). Python (or any other language) "has no way to tell" that just from looks of your algorithm, and yet it's easy to tell that: idx = index_calc() assert idx != 5 -- Best regards, Paul mailto:pmiscml@gmail.com
On Thu, Nov 26, 2020 at 01:27:46PM +1300, Greg Ewing wrote:
On 26/11/20 12:41 pm, Steven D'Aprano wrote:
a = "abcdef" a[-2] # returns a result
Yes, but did you *intend* that result, or did the -2 result from a calculation that should have returned a positive index but went wrong? Python has no way to tell.
Ah, now the penny drops! You are suggesting that the negative index might be a miscalculation. Okay, fair enough. Be happy that if the index is *sufficiently* negative, it will still raise an out-of-bounds IndexError. But is there something fundamentally harder about verifying your calculation in the half-open interval `-n <= index < n` versus the half-open interval `0 <= index n`? I don't think there is. Personally, I have miscalculated indices and got the wrong *postive*, but still within bounds, value far more than an unwanted negative value. E.g. I expected to calculate an index of 3, but got 7 instead. That's much harder to test against than an unwanted negative: assert index >= 0 and the problem is solved. In any case, as you correctly point out, we're not going to dump negative indices, so this discussion is rather hypothetical. -- Steve
participants (10)
-
edwin@211mainstreet.net
-
Eric Fahlgren
-
Eric V. Smith
-
Greg Ewing
-
Mathew M. Noel
-
nathan.w.edwards@outlook.com
-
Paul Sokolovsky
-
Richard Damon
-
Steele Farnsworth
-
Steven D'Aprano