Bagaimana cara mendapatkan posisi item dalam daftar?

169

Saya mengulangi daftar dan saya ingin mencetak indeks item jika memenuhi kondisi tertentu. Bagaimana saya melakukan ini?

Contoh:

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

Jawaban:

280

Hmmm. Ada jawaban dengan pemahaman daftar di sini, tetapi hilang.

Sini:

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

Contoh:

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

Memperbarui:

Oke, Anda ingin ekspresi generator, kami akan memiliki ekspresi generator. Inilah pemahaman daftar lagi, dalam for for:

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

Sekarang kita akan membangun generator ...

>>> (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

dan cukup bagus, kita dapat menetapkan itu ke variabel, dan menggunakannya dari sana ...

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

Dan untuk berpikir saya digunakan untuk menulis FORTRAN.

Charlie Martin
sumber
6
Setelah mungkin 25 tahun mempertanyakan pemrograman fungsional, saya pikir saya akhirnya mendapatkan petunjuk. Pemahaman daftar adalah da bom.
Charlie Martin
15
Saya kira maksud Anda "huruf tunggal" dan terus terang, nama yang lebih panjang dalam contoh ini tidak akan memiliki konten informasi lagi.
Charlie Martin
2
Terima kasih atas jawaban Anda. Saya pikir komentar @ nailer mungkin berhubungan dengan fakta bahwa Anda menggunakan 'i' dalam dua konteks yang berbeda dalam satu baris dalam contoh generator; satu di dalam pemahaman, dan yang lain untuk beralih melalui itu. Aku tahu itu membuatku berhenti sejenak.
Brown
1
@CharlieMartin Anda menggunakan 'i' untuk indeks daripada item per satu konvensi umum untuk variabel karakter tunggal. Memberi nama 'indeks' indeks dan item 'item' akan menghapus ambiguitas. Selain itu, Anda membalas orang tua yang menggunakan 'item' dan 'posisi' dan sebaiknya tidak mengubah nama bagian dari kode asli dalam jawaban Anda.
mikemaccana
1
Sintaks super: o) Anda dapat dengan mudah mendapatkan parameter baris perintah. Biarkan ada sebuah array dari argumen: args = ['x', '-p1', 'v1', '-p2', 'v2']. Kemudian perintah args[[i for i, x in enumerate(args) if x == '-p1'][0] + 1]kembali'v1'
Theodor Keinstein
170

Bagaimana dengan yang berikut ini?

print testlist.index(element)

Jika Anda tidak yakin apakah elemen yang dicari sebenarnya ada dalam daftar, Anda bisa menambahkan pemeriksaan pendahuluan, seperti

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

atau

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

atau "cara pythonic", yang tidak terlalu saya sukai karena kode kurang jelas, tetapi kadang-kadang lebih efisien,

try:
    print testlist.index(element)
except ValueError:
    pass
mmj
sumber
5
alih-alih menguji sebelum mengakses, Anda juga bisa mencoba dan memeriksaValueError
kratenko
Saya pikir dia ingin menemukan semua kejadian, Anda tampaknya hanya memberikan yang pertama.
tfv
@ tfv Saya tidak melihat bagaimana Anda bisa sampai pada kesimpulan seperti itu karena pertanyaannya mengatakan "item" dan bukan "item".
mmj
40

Gunakan enumerasi:

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position
zdan
sumber
10
for i in xrange(len(testlist)):
  if testlist[i] == 1:
    print i

xrange bukan rentang seperti yang diminta (lihat komentar).

Jakber
sumber
ganti range () dengan xrange () - range () membuat daftar, xrange () membuat iterator. xrange () menggunakan lebih sedikit memori, dan panggilan inital lebih cepat.
gnud
2
Saya setuju untuk daftar besar dalam program python 2. Perhatikan bahwa 'range' masih akan bekerja di python 3 (dan bekerja seperti xrange IIRC). 'xrange' akan mengikuti cara dinosaurus.
jakber
2
Pembaruan: xrangedihapus dalam Python 3.x, karena yang baru rangeadalah yang lamaxrange
tim-oh
5

Inilah cara lain untuk melakukan ini:

try:
   id = testlist.index('1')
   print testlist[id]
except ValueError:
   print "Not Found"
Phil Rankin
sumber
3
[x for x in range(len(testlist)) if testlist[x]==1]
pengguna1713952
sumber
2

Coba yang berikut ini:

testlist = [1,2,3,5,3,1,2,1,6]    
position=0
for i in testlist:
   if i == 1:
      print(position)
   position=position+1
B Prashantkumar
sumber
1

Jika daftar Anda menjadi cukup besar dan Anda hanya diharapkan untuk menemukan nilai dalam sejumlah indeks, pertimbangkan bahwa kode ini dapat mengeksekusi lebih cepat karena Anda tidak perlu mengulangi setiap nilai dalam daftar.

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

Jika Anda berharap untuk menemukan nilai banyak Anda mungkin harus menambahkan "indeks" ke daftar dan mencetak daftar di akhir untuk menghemat waktu per iterasi.


sumber
Saya melakukan beberapa tes waktu. Teknik pemahaman daftar berjalan 38% lebih cepat dari kode ini. (Saya mengganti pernyataan cetak Anda dengan panggilan outputlist.append)
Deestan
Saya juga melakukan beberapa tes dengan ukuran daftar 100000 nilai acak antara 1 dan 100. Kode yang saya tulis dalam beberapa kasus dua kali lebih cepat. Tidak ada pengujian waktu yang sebanding dengan aplikasi poster (tentu saja mereka harus menguji diri mereka sendiri). Saya minta maaf jika pendapat saya merusak posting ini.
0

Saya pikir mungkin ada gunanya menggunakan metode curselection () dari library Tkinter thte:

from Tkinter import * 
listbox.curselection()

Metode ini berfungsi pada widget listbox Tkinter, jadi Anda harus membuat salah satunya daripada daftar.

Ini akan mengembalikan posisi seperti ini:

('0',) (meskipun versi Tkinter nantinya dapat mengembalikan daftar ints sebagai gantinya)

Yang mana untuk posisi pertama dan nomor akan berubah sesuai dengan posisi item.

Untuk informasi lebih lanjut, lihat halaman ini: http://effbot.org/tkinterbook/listbox.htm

Salam pembuka.

xXAngelJinXx
sumber
1
Ide yang menarik. Karena ini mengharuskan mengimpor seluruh pustaka Tkinter, itu bukan cara yang paling efisien untuk menyelesaikan masalah.
seaotternerd
3
Ini adalah jalan yang tidak efisien dan berkelok-kelok sehingga saya akan mengatakan itu adalah jawaban yang salah, bahkan jika itu menjawab pertanyaan itu.
Jawaban ini tidak ada hubungannya dengan pertanyaan.
Cody Piersall
0

Mengapa menyulitkan?

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

Hanya untuk menggambarkan contoh lengkap beserta input_listyang memiliki searies1(contoh: input_list [0]) di mana Anda ingin melakukan pencarianseries2 (contoh: input_list [1]) dan dapatkan indeks seri2 jika ada di seri1.

Catatan: Anda certain conditionakan menggunakan ekspresi lambda jika kondisinya sederhana

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)

keluaran:

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

Saya kira itulah yang Anda inginkan. ;-) 'id' akan selalu menjadi indeks nilai-nilai pada daftar.

Leonardo
sumber