「for」ループでインデックスにアクセスしますか?


3605

for次のようなループでインデックスにアクセスするにはどうすればよいですか?

ints = [8, 23, 45, 12, 78]
for i in ints:
    print('item #{} = {}'.format(???, i))

この出力を取得したい:

item #1 = 8
item #2 = 23
item #3 = 45
item #4 = 12
item #5 = 78

ループを使用してforループする場合、この場合は1から5までのループインデックスにどのようにアクセスしますか?


42
Pythonのインデックスは0から始まるので、サンプルリストのインデックスは1から5ではなく0から4であることに注意してください
plugwash

回答:


6117

インデックス変数(通常はCやPHPなどの言語で使用します)などの追加の状態変数を使用すると、Python以外と見なされます。

より良いオプションはenumerate()、Python 2と3の両方で利用可能な組み込み関数を使用することです:

for idx, val in enumerate(ints):
    print(idx, val)

チェックアウトPEP 279を多くのため。


61
Aaronが以下で指摘するように、0-4の代わりに1-5を取得したい場合は、start = 1を使用します。
clozach

2
enumerate別のオーバーヘッドが発生しませんか?
TheRealChx101

私のテスト(Python 3.6.3)によると@ TheRealChx101違いはごくわずかで、場合によってはを支持していenumerateます。
Błotosmętek

804

forループを使用して、ループインデックス(この場合は1から5)にアクセスするにはどうすればよいですか?

enumerate反復しながら要素を使用してインデックスを取得するために使用します。

for index, item in enumerate(items):
    print(index, item)

また、Pythonのインデックスはゼロから始まるため、上記では0〜4になることに注意してください。1から5までのカウントが必要な場合は、次のようにします。

for count, item in enumerate(items, start=1):
    print(count, item)

ユニディオマティック制御フロー

あなたが求めているのは、Pythonicで以下に相当するものです。これは、低レベル言語のほとんどのプログラマが使用するアルゴリズムです。

index = 0            # Python's indexing starts at zero
for item in items:   # Python's for loops are a "for each" loop 
    print(index, item)
    index += 1

または、for-eachループがない言語の場合:

index = 0
while index < len(items):
    print(index, items[index])
    index += 1

またはPythonで見つかることもあります(ただし、一義的に):

for index in range(len(items)):
    print(index, items[index])

列挙関数を使用する

Pythonのenumerate関数は、インデックスのアカウンティングを非表示にし、イテラブルを別のイテラブル(enumerateオブジェクト)にカプセル化することにより、視覚的な混乱を減らします。これは次のようになります。

for index, item in enumerate(items, start=0):   # default is zero
    print(index, item)

このコードサンプルは、Pythonの慣用的なコードとそうでないコードの違いの標準的な例です。慣用的なコードは洗練された(しかし複雑ではない)Pythonであり、意図された方法で記述されています。慣用的なコードは言語の設計者に期待されています。つまり、通常、このコードは読みやすくなるだけでなく、効率も向上します。

カウントを取得する

インデックスは必要ないが、反復の数が必要な場合(場合によっては望ましい)から始めて1、最後の数がカウントになります。

for count, item in enumerate(items, start=1):   # default is zero
    print(item)

print('there were {0} items printed'.format(count))

1から5にしたいと言ったとき、カウントは、(インデックスではなく)要求するつもりであるようです。


それを分解する-ステップバイステップの説明

これらの例を分解するために、インデックスで反復したい項目のリストがあるとしましょう:

items = ['a', 'b', 'c', 'd', 'e']

次に、この反復可能オブジェクトを列挙に渡して、列挙オブジェクトを作成します。

enumerate_object = enumerate(items) # the enumerate object

このイテラブルから、next関数でループする最初の項目を取得できます。

iteration = next(enumerate_object) # first iteration from enumerate
print(iteration)

そして0、最初のインデックスであると'a'最初のアイテムであるのタプルを取得していることがわかります。

(0, 'a')

シーケンスのアンパック」と呼ばれるものを使用して、この2つのタプルから要素を抽出できます。

index, item = iteration
#   0,  'a' = (0, 'a') # essentially this.

検査するindexと、最初のインデックス0をitem参照し、最初の項目を参照していることがわかります'a'

>>> print(index)
0
>>> print(item)
a

結論

  • Pythonインデックスはゼロから始まります
  • 反復処理中に反復可能オブジェクトからこれらのインデックスを取得するには、列挙関数を使用します
  • enumerateを慣用的な方法で(タプルのアンパックと共に)使用すると、より読みやすく保守しやすいコードが作成されます。

これを行います:

for index, item in enumerate(items, start=0):   # Python indexes start at zero
    print(index, item)

1
が空の場合、「カウントの取得」の例itemsは機能しますか?
ベルギ

ajaxを使用してDjangoビューにデータを、値がの変数legDataの 2つの値の形式で配列として送信しています[1406, 1409]。を使用してコンソールprint(legData)に出力すると、出力は[1406,1409]になります。ただし、リストの個々の値をのように解析しようとするfor idx, xLeg in enumerate(legData): print(idx, xLeg)と、インデックス0、1、2、3、4に対して、[、1、4、0、6などの個々の整数の出力が得られますなど(そうです、角括弧とコンマもデータ自体の一部であるかのように出力されます)。ここで何が問題になっていますか?
user12379095

@ user12379095おそらくデータが間違ったタイプ(文字列)であり、それを文字列ではなく実際の数値リストに変換する必要があります。これはやや話題から外れています。コメントが表示されたら削除してください。
アーロンホール

152

それ1以外から起動するのはとても簡単です0

for index, item in enumerate(iterable, start=1):
   print index, item

注意

重要なヒントですindexが、tuple (idx, item)ここにあるので少し誤解を招きます。行ってもいい。


11
問題はリストのインデックスに関するものでした。それらは0から始まるので、インデックスが間違っているため、他の番号から始める意味はほとんどありません(そうです、OPは質問でも間違っていると言っています)。そうでなければ、のタプルである変数を呼び出すindex, itemだけでindex、あなたが述べたように非常に、誤解されています。だけを使用してくださいfor index, item in enumerate(ints)
Antti Haapala 2016年

1
より良い、それが両方のPythonのバージョン2と3で動作します、(インデックス)として括弧のペア内のインデックスを囲むことである
hygull

1
@AnttiHaapalaその理由は、私が推測するところによると、質問の予想される出力は0ではなくインデックス1から始まるためです
pushkin

90
for i in range(len(ints)):
   print i, ints[i]

10
これはおそらくxrange3.0より前のバージョンです。
ベンブランク

43
代わりにenumerateを使用してください
saulspatz '

3
上記のPython 2.3の場合、Pythonのほうが多いため、enumerate組み込み関数を使用します。
januarvs 2017年

列挙は必ずしも優れているとは限りません。アプリケーションの要件によって異なります。私の現在の状況では、オブジェクトの長さ間の関係は私のアプリケーションにとって意味があります。列挙を使用して始めましたが、列挙するオブジェクトを選択するためのロジックを記述する必要を回避するために、このアプローチに切り替えました。
追加

1
@adgどのようにしenumerateてロジックが保存されないかわかりません。インデックスを付けるオブジェクトを選択する必要がありますiか?
chepner 2017

47

Pythonの標準であるように、これを行うにはいくつかの方法があります。すべての例で、次のことを前提としています。lst = [1, 2, 3, 4, 5]

1. enumerateを使用する(ほとんどの慣用句と見なされる

for index, element in enumerate(lst):
    # do the things that need doing here

無限再帰に入る可能性がなくなったので、これは私の意見では最も安全なオプションでもあります。アイテムとそのインデックスの両方が変数に保持され、アイテムにアクセスするためのコードを記述する必要はありません。

2.インデックスを保持する変数を作成する(を使用for

for index in range(len(lst)):   # or xrange
    # you will have to write extra code to get the element

3.インデックスを保持する変数を作成する(を使用while

index = 0
while index < len(lst):
    # you will have to write extra code to get the element
    index += 1  # escape infinite recursion

4.常に別の方法があります

前に説明したように、ここでは説明されていない方法が他にもあり、他の状況ではさらに適用される場合があります。たとえばitertools.chain、for を使用します。ネストされたループを他の例よりもうまく処理します。


30

昔ながらの方法:

for ix in range(len(ints)):
    print ints[ix]

リスト内包表記:

[ (ix, ints[ix]) for ix in range(len(ints))]

>>> ints
[1, 2, 3, 4, 5]
>>> for ix in range(len(ints)): print ints[ix]
... 
1
2
3
4
5
>>> [ (ix, ints[ix]) for ix in range(len(ints))]
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
>>> lc = [ (ix, ints[ix]) for ix in range(len(ints))]
>>> for tup in lc:
...     print tup
... 
(0, 1)
(1, 2)
(2, 3)
(3, 4)
(4, 5)
>>> 

3
これは間違いではなく、C / C ++などで使用されています。Python以外と見なされますが、Pythonでも使用できます。ソースに分解する単純なソリューションのように:+
Valor Naram

一部のpython 過激派はこれをしないでくださいと言います。しかし、私はそれだけで、複数の可能な方法があることを示すために言った
武勇Naram

21

Python 2.7のループ内でリストのインデックスにアクセスする最も速い方法は、小さなリストにはrangeメソッドを使用し、中規模および巨大なリストにはenumerateメソッドを使用することです

参照してください異なるアプローチリストおよびアクセスのインデックス値を反復するために使用することができ、彼らのパフォーマンスメトリック以下のコードサンプルでは(私はあなたのために有用であろうと仮定):

from timeit import timeit

# Using range
def range_loop(iterable):
    for i in range(len(iterable)):
        1 + iterable[i]

# Using xrange
def xrange_loop(iterable):
    for i in xrange(len(iterable)):
        1 + iterable[i]

# Using enumerate
def enumerate_loop(iterable):
    for i, val in enumerate(iterable):
        1 + val

# Manual indexing
def manual_indexing_loop(iterable):
    index = 0
    for item in iterable:
        1 + item
        index += 1

以下の各方法のパフォーマンスメトリックを参照してください。

from timeit import timeit

def measure(l, number=10000):
print "Measure speed for list with %d items" % len(l)
print "xrange: ", timeit(lambda :xrange_loop(l), number=number)
print "range: ", timeit(lambda :range_loop(l), number=number)
print "enumerate: ", timeit(lambda :enumerate_loop(l), number=number)
print "manual_indexing: ", timeit(lambda :manual_indexing_loop(l), number=number)

measure(range(1000))
# Measure speed for list with 1000 items
# xrange:  0.758321046829
# range:  0.701184988022
# enumerate:  0.724966049194
# manual_indexing:  0.894635915756

measure(range(10000))
# Measure speed for list with 100000 items
# xrange:  81.4756360054
# range:  75.0172479153
# enumerate:  74.687623024
# manual_indexing:  91.6308541298

measure(range(10000000), number=100)
# Measure speed for list with 10000000 items
# xrange:  82.267786026
# range:  84.0493988991
# enumerate:  78.0344707966
# manual_indexing:  95.0491430759

結果として、using rangeメソッドは、1000アイテムのリストで最速のものです。サイズが10000を超えるリストの場合、アイテムenumerateが勝者です。

以下に役立つリンクをいくつか追加します。


5
「読みやすさを重視」1000未満の小さな範囲での速度の違いは重要ではありません。すでに小さい時間メトリックでは3%遅くなります。

Python 3の答えを更新してみませんか?
ジョージー

14

まず、インデックスは0〜4です。プログラミング言語は0から数え始めます。それを忘れないでください。そうしないと、インデックスが範囲外の例外に遭遇します。forループで必要なのは、次のように0から4までの変数です。

for x in range(0, 5):

ループは最大値の前に1つの数値を停止するため、0から5を書き込んだことに注意してください。:)

インデックスの値を取得するには

list[index]

13

forループでインデックスにアクセスすると、次のようになります。

for i in enumerate(items): print(i)

items = [8, 23, 45, 12, 78]

for i in enumerate(items):
    print("index/value", i)

結果:

# index/value (0, 8)
# index/value (1, 23)
# index/value (2, 45)
# index/value (3, 12)
# index/value (4, 78)

for i, val in enumerate(items): print(i, val)

items = [8, 23, 45, 12, 78]

for i, val in enumerate(items):
    print("index", i, "for value", val)

結果:

# index 0 for value 8
# index 1 for value 23
# index 2 for value 45
# index 3 for value 12
# index 4 for value 78

for i, val in enumerate(items): print(i)

items = [8, 23, 45, 12, 78]

for i, val in enumerate(items):
    print("index", i)

結果:

# index 0
# index 1
# index 2
# index 3
# index 4

12

この議論によると:http : //bytes.com/topic/python/answers/464012-objects-list-index

ループカウンターの反復

インデックスをループするための現在のイディオムは、組み込みrange関数を使用します。

for i in range(len(sequence)):
    # work with index i

要素とインデックスの両方のループは、古いイディオムまたは新しいzip組み込み関数を使用して実現できます。

for i in range(len(sequence)):
    e = sequence[i]
    # work with index i and element e

または

for i, e in zip(range(len(sequence)), sequence):
    # work with index i and element e

http://www.python.org/dev/peps/pep-0212/経由


22
これは、ジェネレータを反復する場合には機能しません。enumerate()を使用するだけです。
Tadeck 2013年

現在、現在のイディオムは列挙型であり、範囲呼び出しではありません。
TankorSmash


11

あなたはこのコードでそれを行うことができます:

ints = [8, 23, 45, 12, 78]
index = 0

for value in (ints):
    index +=1
    print index, value

ループの最後でインデックス値をリセットする必要がある場合は、このコードを使用します。

ints = [8, 23, 45, 12, 78]
index = 0

for value in (ints):
    index +=1
    print index, value
    if index >= len(ints)-1:
        index = 0

10

この問題の最善の解決策は、列挙型のビルド内Python関数を使用することです。戻りタプルを
列挙 最初の値はインデックス、 2番目の値はそのインデックスの配列の要素

In [1]: ints = [8, 23, 45, 12, 78]

In [2]: for idx, val in enumerate(ints):
   ...:         print(idx, val)
   ...:     
(0, 8)
(1, 23)
(2, 45)
(3, 12)
(4, 78)

9

あなたの質問では、「この場合、1から5までのループインデックスにどのようにアクセスしますか?」

ただし、リストのインデックスはゼロから実行されます。したがって、実際に必要なのは、リスト内の各項目のインデックスと項目か、それとも本当に1から始まる数値が必要かどうかを知る必要があります。幸い、Pythonでは、どちらか一方または両方を簡単に実行できます。

まず、明確にするために、enumerate関数はリスト内の各アイテムのインデックスと対応するアイテムを繰り返し返します。

alist = [1, 2, 3, 4, 5]

for n, a in enumerate(alist):
    print("%d %d" % (n, a))

上記の出力は、

0 1
1 2
2 3
3 4
4 5

インデックスは0から実行されることに注意してください。この種のインデックス付けは、PythonやCを含む最近のプログラミング言語の間で一般的です。

ループをリストの一部に広げたい場合は、リストの一部に標準のPython構文を使用できます。たとえば、リストの2番目のアイテムから最後のアイテムを除くまでループするには、次のように使用できます。

for n, a in enumerate(alist[1:-1]):
    print("%d %d" % (n, a))

ここでも、出力インデックスは0から実行されます。

0 2
1 3
2 4

これにより、のstart=n切り替えが始まりenumerate()ます。これは単にインデックスをオフセットするだけで、ループ内のインデックスに同等に単純に数値を追加できます。

for n, a in enumerate(alist, start=1):
    print("%d %d" % (n, a))

出力は

1 1
2 2
3 3
4 4
5 5

9

繰り返すnums = [1, 2, 3, 4, 5]としたら、

for i, num in enumerate(nums, start=1):
    print(i, num)

または長さを得る l = len(nums)

for i in range(l):
    print(i+1, nums[i])

7

リストに重複する値がない場合:

for i in ints:
    indx = ints.index(i)
    print(i, indx)

1
最初のオプションは、シーケンス内の各アイテムが一意である場合にのみ正しく機能するため、使用しないでください。
Stam Kaly

2
最初のオプションはO(n²)で、これはひどい考えです。リストが1000要素の長さである場合、文字列の使用には、を使用するよりも1000倍長くかかりますenumerate。この回答を削除してください。
ボリス

5

これを試すこともできます:

data = ['itemA.ABC', 'itemB.defg', 'itemC.drug', 'itemD.ashok']
x = []
for (i, item) in enumerate(data):
      a = (i, str(item).split('.'))
      x.append(a)
for index, value in x:
     print(index, value)

出力は

0 ['itemA', 'ABC']
1 ['itemB', 'defg']
2 ['itemC', 'drug']
3 ['itemD', 'ashok']

3

あなたはindex方法を使うことができます

ints = [8, 23, 45, 12, 78]
inds = [ints.index(i) for i in ints]

編集で 重複が存在する場合、このメソッドは機能しないというコメントで強調表示されていintsます。以下のメソッドは、の値に対して機能するはずですints

ints = [8, 8, 8, 23, 45, 12, 78]
inds = [tup[0] for tup in enumerate(ints)]

または代わりに

ints = [8, 8, 8, 23, 45, 12, 78]
inds = [tup for tup in enumerate(ints)]

インデックスと値の両方intsをタプルのリストとして取得する場合。

enumerateこの質問に対する選択された回答での方法を使用しますが、リスト内包表記を使用して、少ないコードでより速くなります。


2

Whileループを使用した簡単な答え:

arr = [8, 23, 45, 12, 78]
i = 0
while i<len(arr):
    print("Item ",i+1," = ",arr[i])
    i +=1

出力:

ここに画像の説明を入力してください


1

forループを使用してリスト内包表記の(インデックス、値)のタプルを出力するには、次のようにします。

ints = [8, 23, 45, 12, 78]
print [(i,ints[i]) for i in range(len(ints))]

出力:

[(0, 8), (1, 23), (2, 45), (3, 12), (4, 78)]

1

これは十分に目的を果たします:

list1 = [10, 'sumit', 43.21, 'kumar', '43', 'test', 3]
for x in list1:
    print('index:', list1.index(x), 'value:', x)

4
これは、各要素を検索するのに必要なO(n ^ 2)時間については言及せずindex()、の最初の出現を検索するようにリストに繰り返し要素がある場合に機能しxなくなります。
Peter Szoldan、

リスト内の重複する要素に対しては機能しないことに完全に同意しました。やっぱり私もパイソンを勉強しています。
Sumit Kumar
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.