Получить индекс недавно добавленного элемента
Есть ли простой способ получить индекс элемента, который я просто добавил в список? Мне нужно отслеживать последний добавленный элемент.
Я придумал два возможных решения:
# 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
, например).