Saya kadang-kadang perlu mengulang daftar dengan Python melihat elemen "saat ini" dan elemen "berikutnya". Saya, sampai sekarang, melakukannya dengan kode seperti:
for current, next in zip(the_list, the_list[1:]):
# Do something
Ini berfungsi dan melakukan apa yang saya harapkan, tetapi apakah ada cara yang lebih idiomatis atau efisien untuk melakukan hal yang sama?
next
cara ini sebagai masker.next
juga merupakan fungsiJawaban:
Inilah contoh yang relevan dari dokumen modul itertools :
Untuk Python 2, Anda perlu
itertools.izip
bukannyazip
:Bagaimana ini bekerja:
Pertama, dua iterator paralel,
a
danb
dibuat (tee()
panggilan), keduanya menunjuk ke elemen pertama dari iterable asli. Iterator kedua,b
digerakkan 1 langkah ke depan (next(b, None)
panggilan) panggilan. Pada titik ini menunjuka
ke s0 danb
menunjuk ke s1. Keduanyaa
danb
dapat melintasi iterator asli secara independen - fungsi izip mengambil dua iterator dan membuat pasangan elemen yang dikembalikan, memajukan kedua iterator pada kecepatan yang sama.Satu peringatan:
tee()
fungsi ini menghasilkan dua iterator yang dapat maju secara independen satu sama lain, tetapi harus dibayar. Jika salah satu iterator bergerak lebih jauh dari yang lain, makatee()
perlu menyimpan elemen yang dikonsumsi dalam memori sampai iterator kedua juga mengkonsumsinya (iterator tidak dapat 'memundurkan' iterator asli). Di sini tidak masalah karena satu iterator hanya 1 langkah di depan yang lain, tetapi secara umum mudah menggunakan banyak memori dengan cara ini.Dan karena
tee()
dapat mengambiln
parameter, ini juga dapat digunakan untuk lebih dari dua iterator paralel:sumber
zip(ł, ł[1:])
jauh lebih pendek dan pythonicfuncy
modulfuncy.pairwise
:: funcy.readthedocs.io/en/stable/seqs.html#pairwiseGulung sendiri!
sumber
Karena
the_list[1:]
sebenarnya membuat salinan seluruh daftar (tidak termasuk elemen pertama), danzip()
membuat daftar tupel segera ketika dipanggil, total tiga salinan daftar Anda dibuat. Jika daftar Anda sangat besar, Anda mungkin lebih sukayang tidak menyalin daftar sama sekali.
sumber
the_list[1:]
hanya membuat objek irisan daripada salinan hampir seluruh daftar - jadi teknik OP tidak terlalu boros seperti yang Anda buat.[1:]
membuat objek slice (atau mungkin "1:
"), yang diteruskan ke__slice__
dalam daftar, yang kemudian mengembalikan salinan yang hanya berisi elemen yang dipilih. Salah satu cara idiomatis untuk menyalin daftar adalahl_copy = l[:]
(yang saya temukan jelek dan tidak dapat dibaca - lebih disukail_copy = list(l)
)__slice__
metode khusus.the_list[1:]
sama denganthe_list[slice(1, None)]
, yang pada gilirannya setara denganlist.__getitem__(the_list, slice(1, None))
.the_list[1:]
hanya salinan dangkal, sehingga hanya terdiri dari satu pointer per item daftar. Bagian yang lebih intensif memori adalahzip()
dirinya sendiri, karena ia akan membuat daftar satutuple
contoh per item daftar, yang masing-masing akan berisi dua petunjuk untuk dua item dan beberapa informasi tambahan. Daftar ini akan mengkonsumsi sembilan kali jumlah memori yang disebabkan oleh[1:]
konsumsi.Saya hanya memadamkannya, saya sangat terkejut tidak ada yang berpikir untuk menghitung ().
sumber
if
juga dapat dihapus jika Anda menggunakan slicing:for (index, thing) in enumerate(the_list[:-1]): current, next_ = thing, the_list[index + 1]
Iterasi dengan indeks dapat melakukan hal yang sama:
Keluaran:
sumber
i
selalu menjadi indeks elemen saat ini.Ini sekarang Impor sederhana pada 16 Mei 2020
Documents untuk lebih banyak itertools Di bawah tenda kode ini sama dengan jawaban yang lain, tapi saya lebih suka impor ketika tersedia.
Jika Anda belum menginstalnya maka:
pip install more-itertools
Contoh
Misalnya jika Anda memiliki urutan fibbonnacci, Anda bisa menghitung rasio pasangan selanjutnya sebagai:
sumber
Pasangan dari daftar menggunakan pemahaman daftar
Keluaran:
sumber
Saya sangat terkejut tidak ada yang menyebutkan solusi umum yang lebih pendek, sederhana dan paling penting :
Python 3:
Python 2:
Ini berfungsi untuk iterasi berpasangan dengan melewati
n=2
, tetapi dapat menangani angka yang lebih tinggi:sumber
Solusi dasar:
sumber
sumber