Pythonda Liste Kısaltmaları
Liste kısaltmaları (list comprehensions), Python diliyle basit, kolay anlaşılır ve hızlı bir şekilde listeler oluşturmamızı sağlar.
Örneğin 0 ile 10 arasındaki ( 0 ve 10 dahil) tam sayıların karelerini hesaplayıp, sonuçları bir liste haline getirelim.
Bu işlemin en basit yöntemi for döngüsü kullanmaktır.
1 2 3 4 |
s1=[] for n in range(11): s1.append(n**2) print(s1) |
Aynı listeyi list ve map fonksiyonları kullanarak da oluşturabiliriz:
1 2 |
s2=list(map(lambda n: n**2, range(11))) print(s2) |
Üçüncü yöntemimiz ise liste kısaltması kullanmaktır:
1 2 |
s3=[n**2 for n in range(11)] print(s3) |
Her üç yöntemin sonucu da aynıdır:
1 2 3 |
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100] [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100] [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100] |
Şimdi 5 ile 18 arasındaki (5 ve 18 dahil) sayılarla 2’nin üssünü hesaplayalım:
1 2 3 4 5 6 7 8 |
s1=[] for n in range(5,19): s1.append(2**n) s2=list(map(lambda n: 2**n, range(5,19))) s3=[2**n for n in range(5,19)] print(s1); print(s2); print(s3) |
Sonuçlar aynı:
1 2 3 |
[32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072] [32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072] [32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072] |
3 ile 28 arasındaki çift sayılar:
1 2 3 4 5 6 7 |
s1=[] for n in range(3,28): if n % 2 == 0: s1.append(n) s2=list(filter(lambda n:n%2==0,range (3,28))) s3=[n for n in range(3,28) if n % 2 == 0] print(s1); print(s2); print(s3) |
Sonuçlar aynı:
1 2 3 |
[4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26] [4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26] [4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26] |
2 ile 24 arasındaki tek sayılar için liste kısaltması:
1 2 |
s =[n for n in range(2,25) if n % 2 == 1] print(s) |
Sonuçlar:
1 |
[3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23] |
Kısacası yinelenebilir (iterable) bir nesneden bir liste oluşturmak istediğimizde:
1 |
[x for x in yinelenebilir] |
Liste kısaltmamıza filtre uygulamak içinse if anahtar sözcüğünü kullanıyoruz:
1 |
[x for x in yinelenebilir if kosul] |
Bir önceki yazımda liste kısaltmalarının for döngülerinden ve map() fonksiyonundan daha hızlı çalıştığını belirtmiştim.
Şimdi bu kıyaslamayı basit bir örnek üzerinden kendimiz yapalım. Kıyaslama işleminde bir dekoratör fonksiyonu kullanalım.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import time def dekorator(func): def ara_func(): t0 = time.time() func() dt = time.time()-t0 print(f"{func.__name__} Süre: {dt}") return ara_func N=10000000 @dekorator def for_fonk(): liste = [] for n in range(N): liste.append(n**3) return liste @dekorator def map_fonk(): liste = list(map(lambda n: n**3, range(N))) return liste @dekorator def lcomp_fonk(): liste = [n**3 for n in range(N)] return liste for_fonk() map_fonk() lcomp_fonk() |
Sonuç:
1 2 3 |
for_fonk Süre: 7.299371004104614 map_fonk Süre: 7.067672967910767 lcomp_fonk Süre: 5.921266555786133 |
Elbette bu sonuçlar betiği çalıştırdığınız bilgisayarın çalışma hızına da bağlıdır ama, aynı işlemin farklı yöntemlerle uygulanmasının farklı süreler aldığını açıkça görebiliyoruz.
Eğer yazdığınız kodlar çalışma hızına duyarlı ise, kesinlikle liste kısaltması kullanmanızı öneriyorum. Eğer böyle bir kaygınız yoksa ve Python konusunda çok fazla deneyiminiz bulunmuyorsa, for yöntemini kullanın. Böylece map veya liste kısaltmasının içeriğini algılamak için çaba sarfetmenize gerek kalmaz.
Şahsen ben, bu konuda Guido van Rossum’a katılıyorum: Eğer çok özel nedenleriniz yoksa lambda, map, filter ve reduce gibi ek araçlara ihtiyacınız olmayacaktır.
Ahmet Aksoy
Referanslar:
- http://www.secnetix.de/olli/Python/list_comprehensions.hawk
- http://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/
- https://code.tutsplus.com/tutorials/list-comprehensions-in-python–cms-26836