Python/sage: can lists start at index 1?

给你一囗甜甜゛ 提交于 2020-07-02 18:14:52

问题


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: Insertion Sort Algorithm

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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!