Получить индекс недавно добавленного элемента

Есть ли простой способ получить индекс элемента, который я просто добавил в список? Мне нужно отслеживать последний добавленный элемент.

Я придумал два возможных решения:

# Workaround 1
# The last added is the one at index len(li) - 1
>> li = ['a', 'b', 'c',]
>> li.append('d')
>> last_index = len(li) - 1
>> last_item = li[len(li) - 1]

# Workaround 2
# Use of insert at index 0 so I know index of last added
>> li = ['a', 'b', 'c',]
>> li.insert(0, 'd')
>> last_item = li[0]

Есть ли трюк, чтобы получить индекс добавленного элемента?

Если нет, то какой из вышеперечисленных вы использовали бы и почему? Вы можете найти любое другое обходное решение?

Ответ 1

li[-1] - последний элемент в списке, и, следовательно, тот, который был недавно добавлен к его концу:

>>> li = [1, 2, 3]
>>> li.append(4)
>>> li[-1]
4

Если вам нужен индекс, а не элемент, то len(li) - 1 просто отлично и очень эффективен (поскольку len(li) вычисляется в постоянное время - см. ниже)


В источнике CPython len для списков отображается функция list_length в Objects/listobject.c:

static Py_ssize_t
list_length(PyListObject *a)
{
    return Py_SIZE(a);
}

Py_SIZE - это просто макрос для доступа к атрибуту размера всех объектов Python, определенному в Include/object.h:

#define Py_SIZE(ob)     (((PyVarObject*)(ob))->ob_size)

Следовательно, len(lst) является по существу единственным разыменованием указателя.

Ответ 2

Вы можете индексировать списки с обеих сторон. Индекс последнего элемента всегда равен -1, вам не нужно вызывать len. Повторное добавление в начале очень неэффективно (требуется, чтобы все элементы в списке перемещались на один пункт вниз).

Ответ 3

Третьим возможным решением может быть подкласс list и переопределить метод append, чтобы он автоматически сохранял свойство, подобное mylist.last_added, когда вы его вызываете.

Этот подход - если он распространен на другие методы списка - дает преимущество в том, что вы могли бы создать класс, в котором он будет отслеживать индекс последнего добавленного элемента независимо от используемого метода (insert, append или простое назначение mylist[some_index] = some_value).

Еще одно преимущество встраивания этой информации в объект списка заключается в том, что вы обойдете ее без необходимости беспокоиться о пространствах имен (так что вы сможете получить ее, даже если ваш список передается с помощью return или yield, например).