You can use slicing:
for item in some_list[2:]:
# do stuff
This will start at the third element and iterate to the end.
Answer from Björn Pollex on Stack OverflowHow do you start a for loop at 1 instead of 0?
python - Can lists start at index 1? - Stack Overflow
python - Starting indexing at 1 instead of 0 - Stack Overflow
python - Start row index from 1 instead of zero without creating additional column in pandas - Stack Overflow
Videos
Index is an object, and default index starts from 0:
>>> result.index
Int64Index([0, 1, 2], dtype=int64)
You can shift this index by 1 with
>>> result.index += 1
>>> result.index
Int64Index([1, 2, 3], dtype=int64)
Just set the index before writing to CSV.
df.index = np.arange(1, len(df) + 1)
And then write it normally.
I am pulling data from a dictionary and appending it to a list, but it appears that dictionary keys start at 1, not 0.
We have been taught to use for loops for this kind of task, but they initialize at 0. Can I start at 1? If not, what is an alternative? Thanks!
for i in range(len(dict)):
<code goes here>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.
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]
Just assign directly a new index array:
df.index = np.arange(1, len(df)+1)
Or if the index is already 0 based, just:
df.index += 1
Example:
In [151]:
df = pd.DataFrame({'a': np.random.randn(5)})
df
Out[151]:
a
0 0.443638
1 0.037882
2 -0.210275
3 -0.344092
4 0.997045
In [152]:
df.index = np.arange(1, len(df)+1)
df
Out[152]:
a
1 0.443638
2 0.037882
3 -0.210275
4 -0.344092
5 0.997045
TIMINGS
For some reason I can't take timings on reset_index but the following are timings on a 100,000 row df:
In [160]:
%timeit df.index = df.index + 1
The slowest run took 6.45 times longer than the fastest. This could mean that an intermediate result is being cached
10000 loops, best of 3: 107 µs per loop
In [161]:
%timeit df.index = np.arange(1, len(df)+1)
10000 loops, best of 3: 154 µs per loop
So without the timing for reset_index I can't say definitively, however it looks like just adding 1 to each index value will be faster if the index is already 0 based
You can also specify the start value using index range like below. RangeIndex is supported in pandas.
#df.index
default value is printed, (start=0,stop=lastelement, step=1)
You can specify any start value range like this:
df.index = pd.RangeIndex(start=1, stop=600, step=1)
Refer: pandas.RangeIndex
Is there a specific reason it was made this way? Personally, it gets confusing when I have to remember that the first character of a string has an index of 0...