2011-07-01 14 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] 

追加されたアイテムのインデックスを取得するためのトリックがあります:

は、私は2つの可能な解決策を思い付きましたか?

これがない場合は、上記のうちどれを使用しますか、なぜですか?あなたが提案した別の回避策はありますか?

答えて

16

li[-1]は、リストの最後の項目、したがって、最近その最後に追加されたものです:あなたは、インデックス、いないアイテムが必要な場合は、その後、len(li) - 1だけで結構です

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

、および非常に効率的な - はCPythonのソースで


を(len(li)が一定時間内に計算されるので、下記参照)、リストのlenがでlist_length機能にマッピングされます:

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

したがって、len(lst)は、本質的に単一のポインタ参照である:

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

Py_SIZEInclude/object.hで定義されているすべてのPythonオブジェクトのサイズ属性にアクセスするためのだけのマクロです。

+0

len(li)の効率についての素晴らしい点です。ありがとう! – romeroqj

+0

@horhay:あなたがそれを気に入って以来、直接ソース* –

+0

より深く進んでいただきました。 :) – romeroqj

3

どちらの側からでもインデックスを作成できます。最後の要素のインデックスは常に-1です。lenに電話する必要はありません。冒頭に繰り返し挿入するのは非常に非効率的です(リスト内のすべての要素を1つ下に移動する必要があります)。

+2

私の理解では、OPは「再利用可能/絶対」インデックスを求めていました。言い換えれば、他の要素がリストに追加されても値を追跡するために使用できるインデックスです(-1は「再利用不可能/相対」です...しかし、おそらく私は遠くに考えていますか? – mac

+0

@mac youあなたの提案はすばらしいことだと思いますが、長期的には、あなたがネームスペースについて言及した制限とリターンによるそのインデックスの保存に対処しなければならない可能性があります。 len(li)の効率についてはOKです。あなたの助けをお待ちしております! – romeroqj

3

listをサブクラス化し、appendメソッドをオーバーライドすると、mylist.last_addedなどのプロパティに自動的に格納されるようになります。

このアプローチ - 他のリスト方法に拡張場合 - あなたは、潜在的にそれがappendinsert(関わらず使用方法の最後に追加された要素のインデックスを追跡するクラスを作成することができます利点を提供する、または単純割り当てmylist[some_index] = some_value)。

この情報をリストオブジェクトに埋め込むもう1つの利点は、名前空間について心配することなくその情報を渡すことができることです(リストがreturnまたはyieldなどで渡されても検索できるようになります)。 )。

+0

[collections.MutableSequence](http://docs.python.org/library/collections.html#abcs-abstract-base-classes)[ABC](http://en.wikipedia.org/wiki)のサブクラス化をお勧めします。/Abstract_base_class)を使用します。これにより、拡張リストが使用されるあらゆる方法で「キャッチ」するのが容易になり、5つのメソッドしか実装する必要がありません。 [this](http://stackoverflow.com/questions/241141/python-lazy-list/5104787#5104787)answer(shameless plug)を参照してください。 –

関連する問題