On 20/12/2016 00:49, Steve D'Aprano wrote:
On Mon, 19 Dec 2016 03:21 am, BartC wrote:

On 18/12/2016 10:59, Paul Götze wrote:
Hi John,

there is a nice short article by E. W. Dijkstra about why it makes sense
to start numbering at zero (and exclude the upper given bound) while
slicing a list. Might give a bit of additional understanding.

http://www.cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF

If you can understand threads, OOP design patterns, binary search or C
pointers, counting indexes 0, 1, 2, 3, ... should hold no fears for you.

Who's talking about me? In the area of scripting languages that could be used by people with a wide range of expertise, I would have expected 1-based to be more common.

In Python you can also have a third operand for a range, A:B:C, which
can mean that B is not necessarily one past the last in the range, and
that the A <= i < B condition in that paper is no longer quite true.

You cannot use a simple comparison like A <= i < B to represent a range with
a step-size not equal to 1. How would you specify the sequence:

    2, 4, 6, 8, 10, 12, 14

as a single expression with ONLY an upper and lower bound?

    2 <= i <= 14

clearly doesn't work, and nor does any alternative.

I didn't mean that the expression specifies the range, but that an value in the range satisfies the expression.

In fact, A:B:-1 corresponds to A >= i > B, which I think is the same as
condition (b) in the paper (but backwards), rather (a) which is favoured.

I have no way of knowing what it corresponds to in your head, but in Python,
a slice A:B:-1 corresponds to the elements at indices:

I got the idea for a minute that, since A:B:C specifies a set of indices, and that range(A,B,C) specifies the same set of values, that they are interchangeable. But of course you can't use x[range(A,B,C)] and you can't do 'for i in A:B:C'. [In my, ahem, own language, you can just that...]

    A, A-1, A-2, A-3, ..., B+1

*in that order*.

py> '0123456789'[7:2:-1]
'76543'

When A is 7, B is 2 and C is -1, then

for i in range(-1000,1000):
    if A >=i > B:
        print (i)

displays only the numbers 3,4,5,6,7; the same elements you get, and they satisfy A >= i > B as I said.

Another little anomaly in Python is that when negative indices are used,
it suddenly switches to 1-based indexing! Or least, when -index is
considered:

That's silly. You can get whichever correspondence you like by choosing
values which do or don't match the indices used by Python:

    x = [-3, -2, -1, 0]
    print x[-1]  # Notice the lack of correspondence

    x = [0, 1, 2, 3]
    print x[1]  # Notice the correspondence here

    x = [6, 7, 8, 9]
    print x[1]  # Notice the lack of correspondence here

What's your point?

That point is that indices go 0,1,2,3,... when indexed from the start, and -1,-2,-3,... when indexed from the end.

That means that the THIRD item from the start has index [2], but the THIRD item from the end has index [-3].

(So if you reversed a list x, and wanted the same x[i] element you had before it was reversed, it now has to be x[-(i+1)]. 1-based, the elements would be x[i] and x[-i], a little more symmetric. But with N-based, you wouldn't be able to index from the end at all.)

+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
....^...........^
cut here    and here

That's the fence/fencepost thing I mentioned elsewhere. It comes up also in graphics: if these boxes represent pixels rather than elements, and a function draws a line from pixel 1 to pixel 4 or fills then in, then should pixel 4 be filled in or not?

But if you think of these values as continuous measures from the left edge, rather than as discrete units, and denote them as 1.0 to 4.0, then it becomes more obvious. The 3 pixels between 1.0 and 4.0 are filled in.

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to