问题
I've downloaded from a supposedly serious source a sage script. It doesn't work on my computer, and a quick debugging showed that a problem came from the fact that at some point, the authors were doing as if a n-element list was numbered from 1 to n (whereas the “normal” numbering in Python and (thus) sage is 0..n-1).
What am I missing? Is there a global variable hidden somewhere that changes this convention, like in APL?
Thanks for your help (I hope my question is clear despite my feeble grasp of both English and CSish...)
回答1:
Python (and therefore sage) lists are always numbered from 0, and there isn't a way to change that.
Looking at CPython's source, in http://hg.python.org/cpython/file/70274d53c1dd/Objects/listobject.c on line 449:
static PyObject *
list_item(PyListObject *a, Py_ssize_t i)
{
if (i < 0 || i >= Py_SIZE(a)) {
if (indexerr == NULL) {
indexerr = PyString_FromString(
"list index out of range");
if (indexerr == NULL)
return NULL;
}
PyErr_SetObject(PyExc_IndexError, indexerr);
return NULL;
}
Py_INCREF(a->ob_item[i]);
return a->ob_item[i];
}
The item lookup delegates straight to the underlying C array, and C arrays are always zero-based. So Python lists are always zero-based as well.
回答2:
A simple class that shifts the index for you provides a clean interface to something reusable.
class Array(object):
def __init__(self, items: list) -> None:
self.items = items
def __repr__(self) -> str:
return '{}({})'.format(self.__class__.__name__, self.items)
def __len__(self) -> int:
return len(self.items)
def __contains__(self, item: any) -> bool:
return item in self.items
def __getitem__(self, key: int) -> any:
return self.items[key - 1]
def __setitem__(self, key: int, value: any) -> None:
self.items[key - 1] = value
def __delitem__(self, key: int) -> None:
del self.items[key - 1]
回答3:
Well I too was facing the same idea on how to implement the method of indexing to be start from 1. I wanted to implement the Insertion Sort Algorithm which is as follows:
As we already know python list start from 0, what I did was following:
A = ['dummy',5,2,6,4,1,3]
for j in range(2,len(A)):
key = A[j]
i=j-1
while i>0 and A[i]>key:
A[i+1] = A[i]
i = i-1
A[i+1] = key
A.pop(0)
print A
I Just added a 'Dummy' in index 0, did all the work like in Algorithm and removed the 'dummy' again. This was just a cheating method.
来源:https://stackoverflow.com/questions/7239668/python-sage-can-lists-start-at-index-1