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

Steven D'Aprano steve at pearwood.info
Sun Jan 17 03:33:38 EST 2016


On Sat, Jan 16, 2016 at 04:39:09PM -0600, boB Stepp wrote:

> So in this model of understanding negative list indexing, should it be:
> 
> mylist = [ 100, 200, 300, 400, 500 ]
>           ^    ^    ^    ^    ^   ^
>           -5   -4   -3   -2   -1  ?

Correct.

> 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 "?"?

Slice syntax looks like this:

obj[start:end]  # two argument version
obj[start:end:step]  # three argument version

All three start, end, step are optional and have useful default values. 

start defaults to "the beginning of the object", or 0.

end defaults to "the end of the object", or len(obj).

step defaults to 1.

There's no negative value which you can give as the end argument to 
represent the very end of the list (or string, tuple, etc) but you can 
leave it blank, use None, the length of the object, or some enormously 
huge number you know is bigger than the list:

py> mylist[-2:sys.maxsize]
[400, 500]


> >>>> 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!

-2 or None returns -2
-1 or None returns -1
0 or None returns None

What's going on here?

`or` returns the first value if it is "truthy", otherwise the second 
value. All integers *except zero* are truthy, but zero is like 
false, and will trigger `or` to return the second value, in 
this case None. So we have:

mylist[start:end or None]

is short-hand for:

if end:
    # end could be 1, -1, 2, -2, 3, -3 etc.
    mylist[start:end]
else:
    # end could be 0
    mylist[start:None]


> >>> 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


You can't use None as a lone index, only in a slice.




-- 
Steve


More information about the Tutor mailing list