Map, Filter, Reduce Kavramları

Standard

Merhaba,
Python’daki varsayılan fonksiyonlar, kod yazarken işlerimizi kolaylaştırdığı gibi, yapılan işleri de hızlandırması ayrıca bir avantaj. Kod yazarken en çok ihtiyaç duyduğumuz işler bir listedeki değerlere işlemler yaptırmak, içlerinden bazılarını değiştirmek, bazılarını filtrelemek gibi işler. İşte Map, filter ve reduce kavramları da tam olarak bu işleri çok daha hızlı yapmak için varlar. O halde örneklerle anlatmaya başlayayım;

Map

Herhangi bir listede işlem yapmak için for ile dönmek yerine kullanabileceğimiz harika bir fonksiyon. 2 parametre alıyor, 1.si yapılacak işlem, 2.si işlemin yapılacağı değişken. Bir işlem yaparken, Python’un varsayılan fonksiyon yapısını ne kadar işlemin içerisine katarsak o kadar optimize edilmiş, dolayısıyla hızlı çalışan koda sahip oluyoruz. Bir örnekle ifade edeyim;

Problem:
Elimizde 10000000 veri uzunluğunda bir liste olsun, bu listeyi 2 ile çarpmamız gereksin. Bu işlemi 3 farklı şekilde yapacağız,

  1. Standart yöntem olan for ile
  2. lambda ve map fonksiyonu kullanarak
  3. map fonksiyonu kullanarak ancak metod yardımıyla
 # Author: Sezer Yavuzer Bozkir <admin@sezerbozkir.com>
# Created Date: 16.11.2017
import random
from time import time


def multiply(x):
    return x * 2


ornek = random.sample(range(1, 10000000), 10000000)

start_time = time()
for order, value in enumerate(ornek):
    ornek[order] = value * 2
end_time = time()

print("Totally time: {}".format(end_time - start_time))

start_time = time()
ornek = list(map(lambda x: x * 2, ornek))
end_time = time()
print("Totally time: {}".format(end_time - start_time))

start_time = time()
ornek = list(map(lambda x: multiply(x), ornek))
end_time = time()
print("Totally time: {}".format(end_time - start_time))

Bu kodu çalıştırdığımızda sonucun lambda ve map ile yapılanının, for’a göre 2 kat daha verimli olduğunu gözlemliyoruz, metod yardımıyla yapılmasınında bu ikisinin arasında kaldığını görüyoruz;

Totally time: 4.464943170547485
Totally time: 2.3204081058502197
Totally time: 2.580265998840332

Filter:

Filter tahmin edebileceğiniz gibi, herhangi bir dizi içerisinde istenilen şarta uygun olanları almak için kullanılmakta. Bu işlem için de fonksiyon 2 değişken almakta, ilki istenen şart, ikincisi ise işlemin yapılacağı liste. Yine bu işlem içinde bir örnek edinip, onun üzerinden gözlemleyelim;

Problem:
Elimizde yine aynı uzunlukta bir liste olduğunu varsayarak, bu listedeki çift sayıları getirelim;

 # Author: Sezer Yavuzer Bozkir <admin@sezerbozkir.com>
# Created Date: 16.11.2017
import random
from time import time

ornek = random.sample(range(1, 10000000), 10000000)

tmp_result_list = []
start_time = time()
for value in ornek:
    if not value % 2:
        tmp_result_list.append(value)
end_time = time()

print("Totally time: {}".format(end_time - start_time))


other_start_time = time()
new_list = list(filter(lambda x: not x % 2, ornek))
other_end_time = time()

print("Totally time: {}".format(other_end_time - other_start_time))

İşlem sonucuna bakalım;

Totally time: 3.430934190750122
Totally time: 3.3554718494415283

Değerlerin birbirine yakın olmasından ziyade, buradaki bir diğer güzellik ise az satır kodla yapılan işlemin önemi. Birinde tek satırla işlem yaparken, diğerinde satır sayısı ve birçok değişken tanımlamamız gerekti.

Reduce:

Bu kavram da, bir liste içerisindeki verilerden nihai bir değer elde etmek istediğimiz zaman kullanabileceğimiz bir fonksiyon. Yine 2 değişken alarak, birinci değişken de yapılacak işlem, 2. değerde de işlem yapılacak listeyi veriyoruz. Bunu da bir örnek ile ifade edelim;

Problem:

Elimizde 10000000 veri uzunluğunda bir liste olsun, bu listedeki sayıların toplamını bulalım;

 # Author: Sezer Yavuzer Bozkir <admin@sezerbozkir.com>
# Created Date: 16.11.2017
import random
from time import time
from functools import reduce

ornek = random.sample(range(0, 10000000), 10000000)

sum_total = 0
start_time = time()
for value in ornek:
    sum_total += value
end_time = time()

print("Totally time: {}".format(end_time - start_time))

other_start_time = time()
other_sum_total = reduce(lambda x, y: x + y, ornek)
other_end_time = time()

print("Totally time: {}".format(other_end_time - other_start_time))

Sonuçlara bakalım;

Totally time: 2.584547758102417
Totally time: 2.8353359699249268

İlginç bir şekilde reduce fonksiyonunun yavaş kaldığını görüyoruz, bunun sebebi lambda olarak ekstra metod yazarak 2’li toplama yaptırıp, bunu 3 değişkende tutması. Daha karmaşık işlemlerde daha performanslı olacağını umuyorum.

Bir dahaki yazımda görüşmek üzere.

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir