私がこのリストを持っているとしましょう:
li = ["a", "b", "a", "c", "x", "d", "a", "6"]
ヘルプが私に示した限り、文字列の最後の出現を返す組み込み関数はありません(の逆のようにindex
)。"a"
それで、基本的に、どのようにして与えられたリストの最後の出現を見つけることができますか?
私がこのリストを持っているとしましょう:
li = ["a", "b", "a", "c", "x", "d", "a", "6"]
ヘルプが私に示した限り、文字列の最後の出現を返す組み込み関数はありません(の逆のようにindex
)。"a"
それで、基本的に、どのようにして与えられたリストの最後の出現を見つけることができますか?
例に示されているように、実際に1文字だけを使用している場合は、便利にstr.rindex
機能します。これにより、ValueError
そのようなアイテムがない場合にaが発生します。これは、発生するのと同じエラークラスlist.index
です。デモ:
>>> li = ["a", "b", "a", "c", "x", "d", "a", "6"]
>>> ''.join(li).rindex('a')
6
list.index
より一般的なケースでは、逆のリストで使用できます。
>>> len(li) - 1 - li[::-1].index('a')
6
ここでスライスすると、リスト全体のコピーが作成されます。短いリストの場合は問題li
ありませんが、非常に大きい場合は、遅延アプローチを使用すると効率が向上する可能性があります。
def list_rindex(li, x):
for i in reversed(range(len(li))):
if li[i] == x:
return i
raise ValueError("{} is not in list".format(x))
ワンライナーバージョン:
next(i for i in reversed(range(len(li))) if li[i] == 'a')
イグナシオのようなワンライナーですが、少しシンプルでクリアなものになります
max(loc for loc, val in enumerate(li) if val == 'a')
私には非常に明確でPythonicのようです。一致する値を含む最高のインデックスを探しています。nexts、lambdas、reversed、またはitertoolsは必要ありません。
他のソリューションの多くは、リスト全体を反復処理する必要があります。これはしません。
def find_last(lst, elm):
gen = (len(lst) - 1 - i for i, v in enumerate(reversed(lst)) if v == elm)
return next(gen, None)
編集:後から考えると、これは不必要な魔法のようです。代わりに次のようなことをします。
def find_last(lst, sought_elt):
for r_idx, elt in enumerate(reversed(lst)):
if elt == sought_elt:
return len(lst) - 1 - r_idx
>>> (x for x in reversed([y for y in enumerate(li)]) if x[1] == 'a').next()[0]
6
>>> len(li) - (x for x in (y for y in enumerate(li[::-1])) if x[1] == 'a').next()[0] - 1
6
私はwimとIgnacioの両方の答えが好きです。itertools
ただし、ラムダにもかかわらず、もう少し読みやすい代替手段を提供すると思います。(Python3の場合;Python 2の場合は、xrange
の代わりに使用しますrange
)。
>>> from itertools import dropwhile
>>> l = list('apples')
>>> l.index('p')
1
>>> next(dropwhile(lambda x: l[x] != 'p', reversed(range(len(l)))))
2
StopIteration
アイテムが見つからない場合、これにより例外が発生します。これをキャッチしてValueError
代わりにレイズすると、これをのように動作させることindex
ができます。
関数として定義され、lambda
ショートカットを回避します。
def rindex(lst, item):
def index_ne(x):
return lst[x] != item
try:
return next(dropwhile(index_ne, reversed(range(len(lst)))))
except StopIteration:
raise ValueError("rindex(lst, item): item not in list")
非charでも機能します。テスト済み:
>>> rindex(['apples', 'oranges', 'bananas', 'apples'], 'apples')
3
dict
辞書キーは一意であり、タプルを使用して作成する場合は、特定のキーの値の最後の割り当てのみが使用されるという事実を利用できます。他の回答で述べられているように、これは小さなリストには問題ありませんが、すべての一意の値のディクショナリを作成し、大きなリストには効率的でない場合があります。
dict(map(reversed, enumerate(li)))["a"]
6
list.rindex
の完全なインターフェースlist.index
(オプションstart
とstop
パラメーターを含む)を提供する、の最も効率的なバージョンを作成する作業を誰かがすでに行っていることを知りたいと思ってここに来ました。この質問への回答、またはここ、またはここ、またはここでそれを見つけられませんでした。だから私はこれを自分でまとめました...これに対する他の回答や他の質問からの提案を利用しています。
def rindex(seq, value, start=None, stop=None):
"""L.rindex(value, [start, [stop]]) -> integer -- return last index of value.
Raises ValueError if the value is not present."""
start, stop, _ = slice(start, stop).indices(len(seq))
if stop == 0:
# start = 0
raise ValueError('{!r} is not in list'.format(value))
else:
stop -= 1
start = None if start == 0 else start - 1
return stop - seq[stop:start:-1].index(value)
他のいくつかの回答で提案されているを使用する手法len(seq) - 1 - next(i for i,v in enumerate(reversed(seq)) if v == value)
は、スペース効率が高くなる可能性があります。完全なリストの逆コピーを作成する必要はありません。しかし、私の(オフハンド、カジュアル)テストでは、約50%遅くなります。
last_occurence=len(yourlist)-yourlist[::-1].index(element)-1
関数をインポートしたり作成したりする必要はありません。
単純なループを使用します。
def reversed_index(items, value):
for pos, curr in enumerate(reversed(items)):
if curr == value:
return len(items) - pos - 1
raise ValueError("{0!r} is not in list".format(value))
lastIndexOf = lambda array, item: len(array) - (array[::-1].index(item)) - 1
リストが小さい場合は、すべてのインデックスを計算して最大のものを返すことができます。
index = max(i for i, x in enumerate(elements) if x == 'foo')
これは、リスト内の要素の最後の出現を見つけるための関数です。リストと要素が関数に渡されます。
li = ["a", "b", "a", "c", "x", "d", "a", "6"]
element = "a"
def last_occurrence(li,element):
for i in range(len(li)-1,0,-1):
if li[i] == element:
return i
return -1
last_occ = last_occurrence(li, element)
if (last_occ != -1):
print("The last occurrence at index : ",last_occ)
else:
print("Element not found")
last_occurrence
関数内では、for
ループが。とともに使用されrange
ます。これにより、リストが逆の順序で繰り返されます。現在のインデックスの要素がsearched
要素と一致する場合、関数はを返しますindex
。リスト内のすべての要素を比較した後、searched
要素が見つからない場合、関数はを返し-1
ます。
@alcaldeのソリューションが大好きですが、ValueErrorに直面しています。条件に一致する要素がない場合、max()argは空のシーケンスです。
エラーセットを回避するにはdefault=None:
max((loc for loc, val in enumerate(li) if val == 'a'), default=None)
def rindex(lst, val):
try:
return next(len(lst)-i for i, e in enumerate(reversed(lst), start=1) if e == val)
except StopIteration:
raise ValueError('{} is not in list'.format(val))
val=[1,2,2,2,2,2,4,5]。
2の最後の発生を見つける必要がある場合
last_occurence = (len(val) -1) - list(reversed(val)).index(2)
enumerate
リスト内包表記を使用して、最後のインデックスを取得するための小さなワンライナーを次に示します。
li = ["a", "b", "a", "c", "x", "d", "a", "6"]
[l[0] for l in enumerate(li) if l[1] == "a"][-1]