2011-07-01 35 views
10

是否有一种直接的方式来获取我刚添加到列表中的项目的索引?我需要跟踪最后添加的项目。获取最近附加的项目的索引

我想出了两种可能的解决方案:

# 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] 

有没有窍门,以获得一个附加项的指数?

如果没有,您会使用上述哪一项,为什么?你建议的任何不同的解决方法?

回答

16

li[-1]是列表中的最后一个项目,因此这是最近追加到结束的一个:

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

如果您需要的指数,而不是项目,然后len(li) - 1是蛮好的,非常有效的(因为len(li)在恒定的时间计算 - 见下文)


在CPython中的源极,用于len列表被映射在起作用:

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)本质上是一个单一指针引用。

+0

关于len(li)效率的好处。谢谢! – romeroqj

+0

@horhay:因为您喜欢它,所以我直接添加了一些更详细的信息*来源* –

+0

感谢您深入了解! :) – romeroqj

3

您可以从任何一方索引列表。最后一个元素的索引始终为-1,因此不需要拨打len。在开始反复插入效率非常低(要求将列表中的所有元素向下移动一个位置)。

+2

我的理解是OP要求一个“可重用/绝对”索引。换句话说,即使其他元素被追加到列表中,也可以用来跟踪值的索引(-1是“不可重复使用/相对的”...但是也许我在想远吗? – mac

+0

@mac you实际上我认为你的建议是一个很好的建议,但从长远来看,我可能不得不应对你提到的关于命名空间的限制以及通过返回来保存该索引。现在@Eli Bendersky澄清关于len(li)的效率是好的感谢您的帮助! – romeroqj

3

第三种可能的解决方案是子类list并覆盖append方法,以便在您调用它时自动存储在像mylist.last_added这样的属性中。

这种做法 - 如果扩展到其他目录的方法 - 提供你可能会创建一个类的地方将继续跟踪最后添加的元素的指数无论使用何种方法的insertappend或优势简单的分配mylist[some_index] = some_value)。

将此信息嵌入到列表对象中的另一个优点是您可以绕过它而无需担心命名空间(因此即使您的列表通过returnyield传递,您也可以检索它) )。

+0

我建议继承[collections.MutableSequence](http://docs.python.org/library/collections.html#abcs-abstract-base-classes)[ABC](http://en.wikipedia.org/wiki/Abstract_base_class)而不是列表。这样可以更容易地“捕捉”扩展列表的每种使用方式,并且只需要实现5种方法。看[这](http://stackoverflow.com/questions/241141/python-lazy-list/5104787#5104787)回答(无耻插件)。 –