Solusi sampai saat ini hanya berurusan dengan daftar, dan kebanyakan adalah menyalin daftar tersebut. Dalam pengalaman saya, banyak kali hal itu tidak mungkin.
Juga, mereka tidak berurusan dengan fakta bahwa Anda dapat memiliki elemen berulang dalam daftar.
Judul pertanyaan Anda mengatakan "Nilai sebelumnya dan berikutnya di dalam satu lingkaran ", tetapi jika Anda menjalankan sebagian besar jawaban di sini di dalam loop, Anda akan berulang kali mengulang seluruh daftar di setiap elemen untuk menemukannya.
Jadi saya baru saja membuat fungsi itu. menggunakanitertools
modul, membagi dan memotong iterable, dan menghasilkan tupel dengan elemen sebelumnya dan berikutnya bersama-sama. Tidak persis seperti yang dilakukan kode Anda, tetapi patut untuk dilihat, karena mungkin dapat menyelesaikan masalah Anda.
from itertools import tee, islice, chain, izip
def previous_and_next(some_iterable):
prevs, items, nexts = tee(some_iterable, 3)
prevs = chain([None], prevs)
nexts = chain(islice(nexts, 1, None), [None])
return izip(prevs, items, nexts)
Kemudian gunakan dalam satu lingkaran, dan Anda akan memiliki item sebelumnya dan berikutnya di dalamnya:
mylist = ['banana', 'orange', 'apple', 'kiwi', 'tomato']
for previous, item, nxt in previous_and_next(mylist):
print "Item is now", item, "next is", nxt, "previous is", previous
Hasil:
Item is now banana next is orange previous is None
Item is now orange next is apple previous is banana
Item is now apple next is kiwi previous is orange
Item is now kiwi next is tomato previous is apple
Item is now tomato next is None previous is kiwi
Ini akan bekerja dengan daftar ukuran apa pun (karena tidak menyalin daftar), dan dengan iterable apa pun (file, set, dll). Dengan cara ini Anda bisa mengulang urutan, dan memiliki item sebelumnya dan berikutnya tersedia di dalam loop. Tidak perlu mencari lagi item tersebut secara berurutan.
Penjelasan singkat tentang kode tersebut:
tee
digunakan untuk membuat 3 iterator independen secara efisien di atas urutan input
chain
menghubungkan dua urutan menjadi satu; ini digunakan di sini untuk menambahkan urutan elemen tunggal[None]
keprevs
islice
digunakan untuk membuat urutan semua elemen kecuali yang pertama, lalu chain
digunakan untuk menambahkan aNone
ke ujungnya
- Sekarang ada 3 urutan independen berdasarkan
some_iterable
tampilan tersebut:
prevs
: None, A, B, C, D, E
items
: A, B, C, D, E
nexts
: B, C, D, E, None
- akhirnya
izip
digunakan untuk mengubah 3 urutan menjadi satu urutan triplet.
Perhatikan bahwa izip
berhenti ketika urutan input apa pun habis, jadi elemen terakhir prevs
akan diabaikan, yang benar - tidak ada elemen sehingga elemen terakhir akan menjadi miliknya prev
. Kami dapat mencoba untuk melepaskan elemen terakhir dari prevs
tapiizip
perilaku membuatnya menjadi berlebihan
Juga mencatat bahwa tee
, izip
, islice
danchain
berasal dari itertools
modul; mereka beroperasi pada urutan masukan mereka secara on-the-fly (malas), yang membuatnya efisien dan tidak memperkenalkan kebutuhan untuk memiliki seluruh urutan dalam memori sekaligus setiap saat.
Dalam python 3
, ia akan menampilkan kesalahan saat mengimpor izip
, Anda dapat menggunakan zip
bukan izip
. Tidak perlu impor zip
, itu adalah standar di python 3
- sumber