リスト内のアイテムの位置を取得するにはどうすればよいですか?


169

リストを繰り返し処理しており、特定の条件を満たすアイテムのインデックスを印刷したい。どうすればいいですか?

例:

testlist = [1,2,3,5,3,1,2,1,6]
for item in testlist:
    if item == 1:
        print position

回答:


280

うーん。ここにリスト内包の答えがありましたが、消えました。

ここに:

 [i for i,x in enumerate(testlist) if x == 1]

例:

>>> testlist
[1, 2, 3, 5, 3, 1, 2, 1, 6]
>>> [i for i,x in enumerate(testlist) if x == 1]
[0, 5, 7]

更新:

さて、あなたはジェネレータ式が必要です、ジェネレータ式があります。forループのリスト内包表記を次に示します。

>>> for i in [i for i,x in enumerate(testlist) if x == 1]:
...     print i
... 
0
5
7

次に、ジェネレータを作成します...

>>> (i for i,x in enumerate(testlist) if x == 1)
<generator object at 0x6b508>
>>> for i in (i for i,x in enumerate(testlist) if x == 1):
...     print i
... 
0
5
7

そして十分に気が利くと、それを変数に割り当て、そこから使用できます...

>>> gen = (i for i,x in enumerate(testlist) if x == 1)
>>> for i in gen: print i
... 
0
5
7

そして、私がFORTRANを書いていたと思います。


6
おそらく25年間関数型プログラミングに疑問を投げかけた後、ようやく手掛かりを得たと思います。リスト内包はダボムです。
チャーリーマーティン

15
私はあなたが「単一の手紙」を意​​味していると思います、そして率直に言って、この例のより長い名前はそれ以上の情報内容を持ちません。
チャーリーマーティン

2
すばらしい答えをありがとう。@nailerのコメントは、ジェネレーターの例の1行で2つの異なるコンテキストで 'i'を使用しているという事実に関連していると思います。1つは理解度の内部にあり、もう1つは理解度を反復します。私はそれが一瞬私を捨てたのを知っています。
ブラウン

1
@CharlieMartin単一文字変数の一般的な慣例に従って、項目ではなく「i」をインデックスに使用します。インデックス「index」とアイテム「item」に名前を付けると、あいまいさがなくなります。さらに、「アイテム」と「位置」を使用した親に返信しているので、回答の元のコードの一部の名前を不必要に変更しないようにするのが良い方法です。
mikemaccana 2013年

1
スーパー構文:o)コマンドラインパラメータを簡単に取得できます。引数の配列があるとしますargs = ['x', '-p1', 'v1', '-p2', 'v2']。その後、コマンドargs[[i for i, x in enumerate(args) if x == '-p1'][0] + 1]が返されます'v1'
Theodor Keinstein 2014

170

以下についてはどうですか?

print testlist.index(element)

検索する要素が実際にリストにあるかどうかわからない場合は、次のような予備チェックを追加できます

if element in testlist:
    print testlist.index(element)

または

print(testlist.index(element) if element in testlist else None)

または「Pythonicの方法」。コードが明確ではないため、あまり好きではありませんが、効率がよくなる場合があります。

try:
    print testlist.index(element)
except ValueError:
    pass

5
アクセスする前にテストする代わりに、試して確認することもできますValueError
kratenko 2013

私は彼がすべての出現を見つけたいと思っていると思います、あなたは最初のものだけを与えるようです。
TFV

@tfv質問は「アイテム」ではなく「アイテム」と言っているので、どのようにしてこのような結論に到達できるかわかりません。
mmj

40

列挙を使用:

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position

10
for i in xrange(len(testlist)):
  if testlist[i] == 1:
    print i

要求された範囲の代わりにxrange(コメントを参照)。


range()をxrange()で置き換えます-range()はリストを作成し、xrange()はイテレータを作成します。xrange()はwaaaayより少ないメモリを使用し、初期呼び出しはより高速です。
gnud 2008

2
Python 2プログラムの大きなリストに同意します。ただし、「範囲」は引き続きpython 3でも機能します(xrange IIRCのように機能します)。「xrange」は恐竜の道を進んでいます。
jakber 2008

2
アップデートは:xrange新しいのように、Pythonの3.xのにdepractedれるrange古いですxrange
TIM-OHの

5

これを行う別の方法を次に示します。

try:
   id = testlist.index('1')
   print testlist[id]
except ValueError:
   print "Not Found"



1

リストが十分に大きくなり、インデックスの数が少ない場合にのみ値が見つかると予想した場合は、リスト内のすべての値を反復する必要がないため、このコードはるかに速く実行できると考えてください。

lookingFor = 1
i = 0
index = 0
try:
  while i < len(testlist):
    index = testlist.index(lookingFor,i)
    i = index + 1
    print index
except ValueError: #testlist.index() cannot find lookingFor
  pass

多くの値が見つかる場合は、リストに「インデックス」を追加し、最後にリストを印刷して、反復ごとの時間を節約する必要があります。


タイミングテストを行いました。リスト内包手法は、このコードより38%高速に実行されます。(私はあなたの印刷ステートメントをoutputlist.append呼び出しに置き換えました)
Deestan

また、1〜100の100000個のランダムな値のリストサイズでいくつかのテストを行いました。私が書いたコードは、場合によっては2倍の速さでした。投稿者のアプリケーションに匹敵する時間テストはありません(もちろん、確実に自分でテストする必要があります)。私の意見がこの投稿に有害だった場合はお詫び申し上げます。

0

Tkinterライブラリのcurselection()メソッドを使用すると便利だと思います。

from Tkinter import * 
listbox.curselection()

このメソッドはTkinterリストボックスウィジェットで機能するため、リストではなくウィジェットの1つを作成する必要があります。

これは次のような位置を返します:

( '0'、)(ただしTkinterの新しいバージョンでは、代わりにintのリストが返される場合があります)

どちらが最初の位置であり、番号はアイテムの位置に応じて変化します。

詳細については、次のページを参照してください。http//effbot.org/tkinterbook/listbox.htm

こんにちは。


1
面白いアイデア。ただし、これにはTkinterライブラリ全体をインポートする必要があるため、問題を解決するための最も効率的な方法ではありません。
seaotternerd 2013年

3
これは非効率的で曲がりくねった経路であり、たとえ問題にいくらか対処したとしても、それは間違った答えであると私は思います。

この回答は質問とは関係ありません。
Cody Piersall 2014

0

なぜ物事を複雑にするのですか?

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position

0

完全な例を説明するために、次input_listを持っているsearies1(例:input_list [0])で、ルックアップを行います。series2(例:input_list [1])と、それはシリーズ1に存在する場合はシリーズ2のインデックスを取得します。

注:certain condition条件が単純な場合、ラムダ式になります

input_list = [[1,2,3,4,5,6,7],[1,3,7]]
series1 = input_list[0]
series2 = input_list[1]
idx_list = list(map(lambda item: series1.index(item) if item in series1 else None, series2))
print(idx_list)

出力:

[0, 2, 6]

-2
testlist = [1,2,3,5,3,1,2,1,6]
for id, value in enumerate(testlist):
    if id == 1:
        print testlist[id]

それはまさにあなたが欲しいものだと思います。;-) 'id'は常にリスト上の値のインデックスになります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.