[Tutor] s.insert(i, x) explanation in docs for Python 3.4 confusing to me

boB Stepp robertvstepp at gmail.com
Sat Jan 16 17:39:09 EST 2016


On Sat, Jan 16, 2016 at 6:19 AM, Peter Otten <__peter__ at web.de> wrote:
> Steven D'Aprano wrote:
>
>> But slices are slightly different. When you provide two indexes in a
>> slice, they mark the gaps BETWEEN items:
>
> The other explanation that Python uses half-open intervals works for me.
>
>> Now, what happens with *negative* indexes?
>>
>> mylist = [ 100, 200, 300, 400, 500 ]
>> indexes:  ^    ^    ^    ^    ^   ^
>>           -6   -5   -4   -3   -2  -1

So in this model of understanding negative list indexing, should it be:

mylist = [ 100, 200, 300, 400, 500 ]
          ^    ^    ^    ^    ^   ^
          -5   -4   -3   -2   -1  ?

Well, it has to be this; otherwise, the off-by-one error exist.  This
also continues to explain why

mylist.insert(-1, x)

inserts x *before* 500.  But in this model, what should go in the place of "?"?


> Slightly related is a problem that comes up in practice; you cannot specify
> "including the last item" with negative indices:

[...]

> A simple fix is
>
>>>> for i in reversed(range(len(mylist))):
> ...     print(mylist[:-i or None])
> ...
> [100]
> [100, 200]
> [100, 200, 300]
> [100, 200, 300, 400]
> [100, 200, 300, 400, 500]

OK, Peter, all was going smoothly in boB-land until you added your
"fix".  Adding "or None" has me addled!  I tried to clarify things in
the interpreter (I removed "reversed" so that I could deal only with
what I was finding confusing.):

>>> for i in range(len(mylist)):
        print(mylist[:-i])

[]
[100, 200, 300, 400]
[100, 200, 300]
[100, 200]
[100]

Then adding the "or None":

>>> for i in range(len(mylist)):
        print(mylist[:-i or None])

[100, 200, 300, 400, 500]
[100, 200, 300, 400]
[100, 200, 300]
[100, 200]
[100]

So far I've duplicated what you did without the reversed built-in.  So
I tried playing around:

>>> mylist[:0]
[]

This was expected as this is equivalent to mylist[0:0].

>>> mylist[:0 or None]
[100, 200, 300, 400, 500]

The critical portion of the for loop for me to understand, since it
results in [100, 200, 300, 400, 500] instead of the empty list.  But
what the heck is going on here?

>>> mylist[0 or None]
Traceback (most recent call last):
  File "<pyshell#117>", line 1, in <module>
    mylist[0 or None]
TypeError: list indices must be integers, not NoneType

And I am stuck.  I can't figure out why [:0 or None] is legal and what
it is actually doing, while [0 or None] is (a rather obvious)
TypeError.  Please illuminate my darkness!

> The hard part is to remember to test whenever a negative index is
> calculated.

I am assuming that this is relevant to what just came before, the use
of this "or None" check.  Is this correct?


-- 
boB


More information about the Tutor mailing list