Mengakses indeks dalam loop 'untuk'?

3607

Bagaimana cara mengakses indeks dalam satu forlingkaran seperti berikut ini?

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

Saya ingin mendapatkan hasil ini:

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

Ketika saya mengulanginya menggunakan forloop, bagaimana cara mengakses indeks loop, dari 1 hingga 5 dalam hal ini?

Joan Venge
sumber
42
Perhatikan bahwa indeks dalam python mulai dari 0, jadi indeks untuk daftar contoh Anda adalah 0 hingga 4 bukan 1 hingga 5
plugwash

Jawaban:

6120

Menggunakan variabel status tambahan, seperti variabel indeks (yang biasanya Anda gunakan dalam bahasa seperti C atau PHP), dianggap non-pythonic.

Opsi yang lebih baik adalah menggunakan fungsi bawaan enumerate(), tersedia dalam Python 2 dan 3:

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

Lihatlah PEP 279 untuk informasi lebih lanjut.

Mike Hordecki
sumber
61
Seperti yang ditunjukkan Aaron di bawah, gunakan start = 1 jika Anda ingin mendapatkan 1-5 alih-alih 0-4.
clozach
2
Tidak enumeratemenimbulkan overhead lain?
TheRealChx101
@ TheRealChx101 menurut tes saya (Python 3.6.3) perbedaannya diabaikan dan kadang-kadang bahkan mendukung enumerate.
Błotosmętek
806

Menggunakan for for, bagaimana cara mengakses indeks loop, dari 1 hingga 5 dalam hal ini?

Gunakan enumerateuntuk mendapatkan indeks dengan elemen saat Anda mengulanginya:

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

Dan perhatikan bahwa indeks Python dimulai dari nol, sehingga Anda akan mendapatkan 0 hingga 4 dengan yang di atas. Jika Anda ingin menghitung, 1 hingga 5, lakukan ini:

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

Aliran kontrol tidak otomatis

Apa yang Anda minta adalah persamaan Pythonic dari yang berikut, yang merupakan algoritma yang akan digunakan oleh kebanyakan programmer dari bahasa tingkat rendah:

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

Atau dalam bahasa yang tidak memiliki untuk-setiap loop:

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

atau kadang-kadang lebih umum (tetapi tidak langsung) ditemukan dalam Python:

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

Gunakan Fungsi Hitung

enumerateFungsi Python mengurangi kekacauan visual dengan menyembunyikan akuntansi untuk indeks, dan merangkum iterable ke iterable lain ( enumerateobjek) yang menghasilkan dua item tuple indeks dan item yang akan disediakan iterable asli. Itu terlihat seperti ini:

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

Contoh kode ini cukup baik contoh kanonik perbedaan antara kode yang idiomatik dari Python dan kode yang tidak. Kode idiomatik adalah Python yang canggih (tapi tidak rumit), ditulis dengan cara yang seharusnya digunakan. Kode idiomatik diharapkan oleh para perancang bahasa, yang berarti bahwa biasanya kode ini tidak hanya lebih mudah dibaca, tetapi juga lebih efisien.

Mendapatkan hitungan

Sekalipun Anda tidak membutuhkan indeks saat berjalan, tetapi Anda membutuhkan hitungan iterasi (kadang-kadang diinginkan) Anda bisa mulai dengan 1dan angka terakhir akan menjadi hitungan Anda.

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

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

Hitungan tampaknya lebih dari apa yang ingin Anda minta (bukan indeks) ketika Anda mengatakan ingin dari 1 hingga 5.


Memecahnya - penjelasan langkah demi langkah

Untuk memecah contoh-contoh ini, katakan kita memiliki daftar item yang ingin kita ulangi dengan indeks:

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

Sekarang kita meneruskan iterable untuk enumerate, membuat objek enumerate:

enumerate_object = enumerate(items) # the enumerate object

Kita dapat menarik item pertama dari iterable yang akan kita dapatkan dalam satu loop dengan nextfungsi:

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

Dan kami melihat kami mendapatkan tuple dari 0, indeks pertama, dan 'a', item pertama:

(0, 'a')

kita bisa menggunakan apa yang disebut sebagai " sequence unpacking " untuk mengekstrak elemen dari dua tuple ini:

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

dan ketika kami memeriksa index, kami menemukan itu mengacu pada indeks pertama, 0, dan itemmengacu pada item pertama 'a',.

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

Kesimpulan

  • Indeks python mulai dari nol
  • Untuk mendapatkan indeks ini dari iterable saat Anda mengulanginya, gunakan fungsi enumerate
  • Menggunakan enumerasi dengan cara idiomatis (bersama dengan tuple unpacking) menciptakan kode yang lebih mudah dibaca dan dipelihara:

Jadi lakukan ini:

for index, item in enumerate(items, start=0):   # Python indexes start at zero
    print(index, item)
Aaron Hall
sumber
1
Apakah contoh " Mendapatkan hitungan " berfungsi saat itemskosong?
Bergi
Saya mengirim data menggunakan ajax ke pandangan Django sebagai array dalam bentuk dua nilai dalam legData variabel dengan nilai sebagai [1406, 1409]. Jika saya mencetak ke konsol menggunakan print(legData), hasilnya adalah [1406.1409] . Namun, jika saya mencoba mem-parsing nilai-nilai individual dari daftar seperti for idx, xLeg in enumerate(legData): print(idx, xLeg), itu memberi saya output bilangan bulat individual seperti [, 1, 4, 0, 6, dan seterusnya terhadap indeks 0, 1, 2, 3, 4 dll. (ya, tanda kurung & koma juga menjadi output seolah-olah mereka adalah bagian dari data itu sendiri ). Apa yang salah di sini?
user12379095
@ user12379095 Anda mungkin memiliki data dalam tipe yang salah (sebuah string) dan Anda perlu mengonversinya menjadi daftar angka yang sebenarnya, bukan string. Itu agak di luar topik di sini, harap hapus komentar Anda dan tandai milik saya untuk dihapus karena tidak diperlukan lagi ketika Anda melihat ini.
Aaron Hall
153

Cukup mudah untuk memulainya dari 1selain 0:

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

Catatan

Petunjuk penting, meskipun sedikit menyesatkan karena indexakan ada di tuple (idx, item)sini. Baik untuk pergi.

AJ
sumber
11
Pertanyaannya adalah tentang daftar indeks; karena mereka mulai dari 0, tidak ada gunanya memulai dari nomor lain karena indeksnya akan salah (ya, OP mengatakan itu salah dalam pertanyaan juga). Kalau tidak, memanggil variabel yang tuple dari index, itemhanya indexsangat menyesatkan, seperti yang Anda catat. Gunakan saja for index, item in enumerate(ints).
Antti Haapala
1
Lebih baik melampirkan indeks di dalam pasangan kurung sebagai (indeks), itu akan bekerja pada kedua Python versi 2 dan 3.
hygull
1
@AnttiHaapala Alasannya, saya kira, adalah bahwa output yang diharapkan dari pertanyaan dimulai pada indeks 1 sebagai gantinya 0
pushkin
90
for i in range(len(ints)):
   print i, ints[i]
David Hanak
sumber
10
Itu mungkin seharusnya xrangeuntuk pra-3.0.
Ben Blank
44
Gunakan enumerasi sebagai gantinya
saulspatz
3
Untuk Python 2.3 di atas, gunakan enumerate built-in function karena lebih Pythonic.
januarvs
Menghitung tidak selalu lebih baik - tergantung pada persyaratan aplikasi. Dalam situasi saya saat ini, hubungan antara panjang objek bermakna untuk aplikasi saya. Meskipun saya mulai menggunakan enumerate, saya beralih ke pendekatan ini untuk menghindari keharusan menulis logika untuk memilih objek mana yang akan disebutkan.
adg
1
@ Adg Saya tidak melihat bagaimana menghindari enumeratemenyimpan logika apa pun; Anda masih harus memilih objek mana yang akan diindeks i, bukan?
chepner
47

Seperti norma dalam Python ada beberapa cara untuk melakukan ini. Dalam semua contoh, asumsikan:lst = [1, 2, 3, 4, 5]

1. Menggunakan enumerate ( dianggap paling idiom )

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

Ini juga merupakan pilihan paling aman menurut saya karena kesempatan untuk mengalami rekursi tak terbatas telah dihilangkan. Baik item dan indeksnya disimpan dalam variabel dan tidak perlu menulis kode lebih lanjut untuk mengakses item.

2. Membuat variabel untuk menyimpan indeks ( menggunakanfor )

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

3. Membuat variabel untuk menahan indeks ( menggunakanwhile )

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

4. Selalu ada cara lain

Seperti dijelaskan sebelumnya, ada cara lain untuk melakukan ini yang belum dijelaskan di sini dan mereka bahkan dapat menerapkan lebih dalam situasi lain. misalnya menggunakan itertools.chaindengan untuk. Ini menangani loop bersarang lebih baik daripada contoh lainnya.

Charitoo
sumber
30

Cara kuno:

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

Pemahaman daftar:

[ (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)
>>> 
Charlie Martin
sumber
3
Ini tidak salah dan digunakan dalam C / C ++ dan lainnya. Ini dianggap sebagai non-pythonic, tetapi juga dapat digunakan dalam python. Seperti solusi sederhana yang memecahnya ke sumber: +
Valor Naram
Beberapa ekstrimis python akan berkata, jangan lakukan ini. Tapi saya katakan itu hanya untuk menunjukkan bahwa ada lebih dari satu cara yang mungkin
Valor Naram
21

Cara tercepat untuk mengakses indeks daftar dalam loop di Python 2.7 adalah dengan menggunakan metode rentang untuk daftar kecil dan menghitung metode untuk daftar ukuran sedang dan besar.

Silakan lihat berbagai pendekatan yang dapat digunakan untuk beralih dari daftar dan mengakses nilai indeks dan metrik kinerjanya (yang saya kira akan berguna bagi Anda) dalam contoh kode di bawah ini:

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

Lihat metrik kinerja untuk setiap metode di bawah ini:

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

Akibatnya, menggunakan rangemetode adalah yang tercepat hingga daftar dengan 1000 item. Untuk daftar dengan ukuran> 10.000 item enumerateadalah pemenangnya.

Menambahkan beberapa tautan bermanfaat di bawah ini:

Andriy Ivaneyko
sumber
5
"jumlah keterbacaan" Perbedaan kecepatan dalam kisaran kecil <1000 tidak signifikan. Ini 3% lebih lambat pada metrik waktu yang sudah kecil.
Bagaimana dengan memperbarui jawaban untuk Python 3?
Georgy
14

Pertama-tama, indeks akan dari 0 hingga 4. Bahasa pemrograman mulai menghitung dari 0; jangan lupa itu atau Anda akan menemukan indeks di luar batas. Yang Anda butuhkan dalam for loop adalah penghitungan variabel dari 0 hingga 4 seperti:

for x in range(0, 5):

Perlu diingat bahwa saya menulis 0 hingga 5 karena loop berhenti satu angka sebelum maks. :)

Untuk mendapatkan nilai penggunaan indeks

list[index]
ytpillai
sumber
13

Inilah yang Anda dapatkan ketika Anda mengakses indeks dalam forloop:

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

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

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

Hasil:

# 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)

Hasil:

# 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)

Hasil:

# index 0
# index 1
# index 2
# index 3
# index 4
Andy
sumber
12

Menurut diskusi ini: http://bytes.com/topic/python/answers/464012-objects-list-index

Loop iterasi konter

Ungkapan saat ini untuk pengulangan indeks menggunakan fungsi built-in range:

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

Looping kedua elemen dan indeks dapat dicapai baik dengan idiom lama atau dengan menggunakan fungsi zipbuilt-in yang baru:

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

atau

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

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

thinker007
sumber
22
Ini tidak akan berhasil untuk iterasi melalui generator. Cukup gunakan enumerate ().
Tadeck
Saat ini, idiom saat ini adalah menghitung, bukan panggilan jangkauan.
TankorSmash
dan itu sama dengan jawaban yang lebih lama: stackoverflow.com/a/522576/6451573
Jean-François Fabre
11

Anda dapat melakukannya dengan kode ini:

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

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

Gunakan kode ini jika Anda perlu mengatur ulang nilai indeks di akhir loop:

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

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

Solusi terbaik untuk masalah ini adalah menggunakan enumerate in-build function python.
enumerate return tuple
nilai pertama adalah indeks
nilai kedua adalah elemen array pada indeks itu

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)
Anurag Misra
sumber
9

Dalam pertanyaan Anda, Anda menulis "bagaimana cara mengakses indeks loop, dari 1 hingga 5 dalam kasus ini?"

Namun, indeks untuk daftar berjalan dari nol. Jadi, maka kita perlu tahu apakah yang Anda inginkan sebenarnya adalah indeks dan item untuk setiap item dalam daftar, atau apakah Anda benar-benar ingin angka dimulai dari 1. Untungnya, dengan Python, mudah untuk melakukan salah satu atau keduanya.

Pertama, untuk memperjelas, enumeratefungsi berulang indeks dan item terkait untuk setiap item dalam daftar.

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

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

Output untuk di atas adalah,

0 1
1 2
2 3
3 4
4 5

Perhatikan bahwa indeks berjalan dari 0. Jenis pengindeksan ini umum di antara bahasa pemrograman modern termasuk Python dan C.

Jika Anda ingin loop Anda menjangkau bagian dari daftar, Anda bisa menggunakan sintaks Python standar untuk bagian dari daftar. Misalnya, untuk mengulang dari item kedua dalam daftar hingga tetapi tidak termasuk item terakhir, Anda bisa menggunakan

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

Perhatikan bahwa sekali lagi, indeks output berjalan dari 0,

0 2
1 3
2 4

Itu membawa kita ke start=nsaklar untuk enumerate(). Ini hanya mengimbangi indeks, Anda bisa menambahkan angka ke indeks di dalam loop.

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

yang hasilnya adalah

1 1
2 2
3 3
4 4
5 5
DrM
sumber
9

Jika saya mengulangi, nums = [1, 2, 3, 4, 5]saya akan melakukannya

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

Atau dapatkan panjangnya sebagai l = len(nums)

for i in range(l):
    print(i+1, nums[i])
Ankur Kothari
sumber
7

Jika tidak ada nilai duplikat dalam daftar:

for i in ints:
    indx = ints.index(i)
    print(i, indx)
RIshu
sumber
1
Perhatikan bahwa opsi pertama tidak boleh digunakan, karena hanya berfungsi dengan benar hanya ketika setiap item dalam urutan unik.
Stam Kaly
2
Opsi pertama adalah O (n²), ide yang buruk. Jika daftar Anda adalah 1000 elemen, itu akan memakan waktu 1000 kali lebih lama daripada menggunakan enumerate. Anda harus menghapus jawaban ini.
Boris
5

Anda juga dapat mencoba ini:

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)

Outputnya adalah

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

Anda dapat menggunakan indexmetode ini

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

EDIT Disorot dalam komentar bahwa metode ini tidak berfungsi jika ada duplikat ints, metode di bawah ini akan berfungsi untuk nilai apa pun di ints:

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

Atau sebagai alternatif

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

jika Anda ingin mendapatkan kedua indeks dan nilai intssebagai daftar tupel.

Ini menggunakan metode enumeratedalam jawaban yang dipilih untuk pertanyaan ini, tetapi dengan pemahaman daftar, membuatnya lebih cepat dengan kode lebih sedikit.

PyRsquared
sumber
2

Jawaban sederhana menggunakan While Loop:

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

Keluaran:

masukkan deskripsi gambar di sini

Amar Kumar
sumber
1

Untuk mencetak tupel (indeks, nilai) dalam pemahaman daftar menggunakan forloop:

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

Keluaran:

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

Ini melayani tujuan dengan cukup baik:

list1 = [10, 'sumit', 43.21, 'kumar', '43', 'test', 3]
for x in list1:
    print('index:', list1.index(x), 'value:', x)
Sumit Kumar
sumber
4
Ini akan rusak jika ada elemen berulang dalam daftar karena index()akan mencari kejadian pertama x, tidak menyebutkan waktu O ( n ^ 2 ) yang diperlukan untuk mencari setiap elemen.
Peter Szoldan
sepenuhnya setuju bahwa itu tidak akan berfungsi untuk elemen duplikat dalam daftar. lagipula saya juga belajar python.
Sumit Kumar