95

私がこのリストを持っているとしましょう:

li = ["a", "b", "a", "c", "x", "d", "a", "6"]

ヘルプが私に示した限り、文字列の最後の出現を返す組み込み関数はありません(の逆のようにindex)。"a"それで、基本的に、どのようにして与えられたリストの最後の出現を見つけることができますか?

4

16 に答える 16

109

例に示されているように、実際に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')
于 2011-07-31T15:12:51.850 に答える
50

イグナシオのようなワンライナーですが、少しシンプルでクリアなものになります

max(loc for loc, val in enumerate(li) if val == 'a')

私には非常に明確でPythonicのようです。一致する値を含む最高のインデックスを探しています。nexts、lambdas、reversed、またはitertoolsは必要ありません。

于 2014-05-22T20:04:47.743 に答える
18

他のソリューションの多くは、リスト全体を反復処理する必要があります。これはしません。

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
于 2014-04-18T01:39:56.717 に答える
8
>>> (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
于 2011-07-31T15:02:03.327 に答える
7

私はwimIgnacioの両方の答えが好きです。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
于 2011-07-31T20:27:03.287 に答える
5

dict

辞書キーは一意であり、タプルを使用して作成する場合は、特定のキーの値の最後の割り当てのみが使用されるという事実を利用できます。他の回答で述べられているように、これは小さなリストには問題ありませんが、すべての一意の値のディクショナリを作成し、大きなリストには効率的でない場合があります。

dict(map(reversed, enumerate(li)))["a"]

6
于 2018-06-11T16:04:37.940 に答える
2

list.rindexの完全なインターフェースlist.index(オプションstartstopパラメーターを含む)を提供する、の最も効率的なバージョンを作成する作業を誰かがすでに行っていることを知りたいと思ってここに来ました。この質問への回答、またはここ、またはここ、またはここでそれを見つけられませんでした。だから私はこれを自分でまとめました...これに対する他の回答や他の質問からの提案を利用しています。

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%遅くなります。

于 2017-06-26T18:13:47.450 に答える
1
last_occurence=len(yourlist)-yourlist[::-1].index(element)-1

関数をインポートしたり作成したりする必要はありません。

于 2018-04-13T10:09:14.940 に答える
0

単純なループを使用します。

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))
于 2015-06-19T14:07:45.603 に答える
0
lastIndexOf = lambda array, item: len(array) - (array[::-1].index(item)) - 1
于 2020-02-25T21:10:06.840 に答える
0

リストが小さい場合は、すべてのインデックスを計算して最大のものを返すことができます。

index = max(i for i, x in enumerate(elements) if x == 'foo')
于 2020-12-05T01:19:18.263 に答える
0

これは、リスト内の要素の最後の出現を見つけるための関数です。リストと要素が関数に渡されます。

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ます。

于 2021-12-16T09:01:37.117 に答える
0

@alcaldeのソリューションが大好きですが、ValueErrorに直面しています。条件に一致する要素がない場合、max()argは空のシーケンスです。

エラーセットを回避するにはdefault=None

max((loc for loc, val in enumerate(li) if val == 'a'), default=None)
于 2022-02-01T11:08:20.697 に答える
-1
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))
于 2016-08-30T02:57:28.133 に答える
-1

val=[1,2,2,2,2,2,4,5]。

2の最後の発生を見つける必要がある場合

last_occurence = (len(val) -1) - list(reversed(val)).index(2)

于 2017-09-24T11:06:13.710 に答える
-1

enumerateリスト内包表記を使用して、最後のインデックスを取得するための小さなワンライナーを次に示します。

li = ["a", "b", "a", "c", "x", "d", "a", "6"]
[l[0] for l in enumerate(li) if l[1] == "a"][-1]
于 2018-01-04T16:21:21.837 に答える