Yeterince çoğu zaman, bir listeyi çiftler halinde işleme ihtiyacını buldum. Bunu yapmanın pitonik ve verimli yolunun hangisi olacağını merak ediyordum ve bunu Google'da buldum:
pairs = zip(t[::2], t[1::2])
Bunun yeterince pitonik olduğunu düşündüm, ancak son zamanlarda deyimler ile verimlilik arasındaki tartışmanın ardından bazı testler yapmaya karar verdim:
import time
from itertools import islice, izip
def pairs_1(t):
return zip(t[::2], t[1::2])
def pairs_2(t):
return izip(t[::2], t[1::2])
def pairs_3(t):
return izip(islice(t,None,None,2), islice(t,1,None,2))
A = range(10000)
B = xrange(len(A))
def pairs_4(t):
# ignore value of t!
t = B
return izip(islice(t,None,None,2), islice(t,1,None,2))
for f in pairs_1, pairs_2, pairs_3, pairs_4:
# time the pairing
s = time.time()
for i in range(1000):
p = f(A)
t1 = time.time() - s
# time using the pairs
s = time.time()
for i in range(1000):
p = f(A)
for a, b in p:
pass
t2 = time.time() - s
print t1, t2, t2-t1
Bilgisayarımdaki sonuçlar şunlardı:
1.48668909073 2.63187503815 1.14518594742
0.105381965637 1.35109519958 1.24571323395
0.00257992744446 1.46182489395 1.45924496651
0.00251388549805 1.70076990128 1.69825601578
Bunları doğru yorumluyorsam, bu Python'da listelerin, liste indekslemenin ve liste dilimlemenin uygulanmasının çok verimli olduğu anlamına gelmelidir. Hem rahatlatıcı hem de beklenmedik bir sonuçtur.
Bir listeyi çiftler halinde geçmenin başka, "daha iyi" bir yolu var mı?
Listede tek sayıda eleman varsa, sonuncunun hiçbir çift içinde olmayacağına dikkat edin.
Tüm öğelerin dahil edilmesini sağlamanın doğru yolu hangisidir?
Cevaplardan şu iki öneriyi testlere ekledim:
def pairwise(t):
it = iter(t)
return izip(it, it)
def chunkwise(t, size=2):
it = iter(t)
return izip(*[it]*size)
Sonuçlar şunlardır:
0.00159502029419 1.25745987892 1.25586485863
0.00222492218018 1.23795199394 1.23572707176
Şimdiye kadarki sonuçlar
Çoğu pitonik ve çok verimli:
pairs = izip(t[::2], t[1::2])
En verimli ve çok pitonik:
pairs = izip(*[iter(t)]*2)
İlk cevabın iki yineleyici, ikincisinin ise tek bir yineleyici kullandığını düşünmem biraz zaman aldı.
Tek sayıda öğeye sahip dizilerle başa çıkmak için, öneri, None
önceki son öğe ile eşleştirilen bir öğe ( ) ekleyerek orijinal diziyi büyütmek olmuştur , bu da elde edilebilecek bir şeydir itertools.izip_longest()
.
En sonunda
Python 3.x'te olduğu zip()
gibi davrandığını itertools.izip()
ve itertools.izip()
gittiğini unutmayın.