Python'da Fonksiyonel Programlama Kavramları ve Örnekler

Python'da Fonksiyonel Programlama Kavramları ve Örnekler

Python'da Fonksiyonel Programlama Kavramları ve Örnekleri eşliğinde fonksiyonel programlamayı öğrenin İşlevsel programlama stilini benimseyin ve daha verimli kod yazın İleri seviye örneklerle uygulamalı öğrenme keyfini yaşayın

Python'da Fonksiyonel Programlama Kavramları ve Örnekler

Python programlama dilinde fonksiyonel programlama kavramlarının kullanımı oldukça yaygın hale gelmiştir. Fonksiyonel programlama, programcının veriler üzerinde dönüşümsel işlemler yapmasına olanak tanıyan bir programlama yaklaşımıdır. Bu yaklaşımın en önemli özelliklerinden biri, kodun okunabilirliğini ve tekrar kullanılabilirliğini artırmasıdır.

Bu yazıda, Python programlama dilinde fonksiyonel programlama kavramlarına genel bir bakış atacağız ve bu kavramların nasıl kullanılabileceği örneklerle incelenecektir. Yazımızda yer verilecek kavramlar arasında yüksek düzeyde fonksiyonlar, anonim fonksiyonlar, sıralama fonksiyonları, map, filter ve reduce fonksiyonları, dekoratörler ve generator fonksiyonları bulunmaktadır. Yazımız ile bu kavramların kullanımı hakkında bilgi edinmeniz ve pratik tecrübe kazanmanız hedeflenmektedir.


Fonksiyonel Programlama Nedir?

Fonksiyonel programlama, programlama dillerinde kodlamanın bir yaklaşımıdır. Bu yaklaşımda, işlev veya fonksiyonların matematiksel işlevler gibi düşünülmesi ve programlama yapılır. Fonksiyonel programlama yaklaşımı, diğer programlama dillerindeki yapısal ve nesneye dayalı programlama yaklaşımlarından farklıdır.

Bu yaklaşımda, bir fonksiyon her zaman belirli bir girişe yanıt verir. Fonksiyonun işlevi girdilerle sınırlıdır ve girdileri belirtilen çıktılara dönüştürmek için kullanılır. Fonksiyonel programlama dilinin önemli özelliklerinden biri, sınıf belirleyicilerinin kullanılmamasıdır.

Fonksiyonel programlama, karmaşık kodları yönetmek ve yapılması gereken işleri otomatikleştirmek için kullanılabilir. Bu programlama yaklaşımının en büyük avantajı, verimli, ölçeklenebilir ve düzenli kodlar yazmamıza olanak tanımasıdır.


Yüksek Düzeyde Fonksiyonlar

Python'da yüksek düzeyde fonksiyon kullanımı, fonksiyonel programlama için önemli bir araçtır. Yüksek düzeyde fonksiyonlar, başka bir fonksiyonun argüman olarak kullanılabilmesi ve bir fonksiyonun geri döndürebileceği anlamına gelir. Bu özelliğiyle fonksiyonları daha modüler hale getirir ve kod tekrarını önler.

Python'da yüksek düzeyde fonksiyonların bir örneği map() fonksiyonudur. map() fonksiyonu, bir listedeki tüm elemanlara belirli bir işlem yaparak yeni bir listede depolamanızı sağlar. Örneğin, bir sayı listesindeki tüm elemanları karesini alarak yeni bir liste oluşturmak istediğimizi varsayalım. Bu işlemi yapmak için map() fonksiyonu kullanabiliriz. İşlemi yapacak lambda fonksiyonu parametre olarak ileterek işlemimizi gerçekleştirebiliriz.

Eski Liste Yeni Liste
[1, 2, 3, 4, 5] [1, 4, 9, 16, 25]
  • Kod parçası:
  •   numbers = [1, 2, 3, 4, 5]  squared_numbers = list(map(lambda x: x**2, numbers))  print(squared_numbers)  
  • Çıktı:
  •   [1, 4, 9, 16, 25]  

Bir başka yüksek düzeyde fonksiyon reduce() fonksiyonudur. reduce() fonksiyonu, bir dizi elemana uygulanan bir işlem sonucunda tek bir sonuç döndürür. Örneğin, bir sayı listesindeki tüm elemanların toplamını bulmak için reduce() fonksiyonunu kullanabilirsiniz. Bu örnekte lambda fonksiyonuna başlayacak başka bir argüman oluşturmamız gerekiyor. Örneğin, başlangıç değeri 0 olarak belirlenirse, reduce() fonksiyonu, listedeki tüm elemanların toplamını hesaplar.

  • Kod parçası:
  •   from functools import reduce    numbers = [1, 2, 3, 4, 5]  sum = reduce(lambda x, y: x+y, numbers, 0)  print(sum)  
  • Çıktı:
  •   15  

Python'da fonksiyonel programlama kavramları kullanarak daha okunaklı ve modüler kod yazabilirsiniz. Yüksek düzeyde fonksiyonların kullanımı bu amaca ulaşmanıza yardımcı olacaktır.


Anonim Fonksiyonlar (Lambda Functions)

Anonim fonksiyonlar, yani Lambda fonksiyonlar, adından da anlaşılacağı gibi isimsiz fonksiyonlar olarak tanımlanabilir. Bir fonksiyonu tanımlarken def anahtar kelimesi ve fonksiyon adı kullanılırken Lambda fonksiyonu tanımlarken sadece lambda anahtar kelimesi kullanılır.

Genellikle bir kaç kez kullanılacak küçük işlemler için kullanılır. Lambda fonksiyonlarının diğer bir özelliği, bir fonksiyonu başka bir fonksiyona argüman olarak vermek için kullanılır. Kısacası lambda fonksiyonlar, değişken olarak saklanabilen ve programın farklı yerlerinde kullanılabilen isimsiz fonksiyonlardır.

Örneğin;

Kod Açıklama
iki_kati = lambda x: x * 2
Bir sayının iki katını döndürür
terse_cevir = lambda kelime: kelime[::-1]
Verilen kelimeyi tersine çevirir

Yukarıdaki örneklerde Lambda fonksiyonları kullanılarak kolaylıkla bir sayının iki katını hesaplayabilir veya verilen bir kelimeyi ters çevirebiliriz. Kısacası, küçük işlemleri hızlı bir şekilde yapmak için anonim fonksiyonlar oldukça kullanışlıdır.


Örneklerle Lambda Fonksiyon Kullanımı

Lambda fonksiyonları, çoğu zaman kullandığımız standart fonksiyonlar yerine hızlı ve pratik çözümler sunar. Lambda fonksiyonlarının kullanım alanlarının açıklamasını şu örneklerle inceleyelim:

  • Liste Elemanlarına Uygulanması: Lambda fonksiyonları liste elemanlarına uygulanabilir ve her elemanın üzerinde işlem yapılabilir. Örneğin, "numbers" listesi içindeki tüm sayıları iki katına çıkarmak istediğimizde:
Kod Örneği: Çıktı:
numbers = [1, 2, 3, 4, 5]    doubled_numbers = list(map(lambda x: x*2, numbers))    print(doubled_numbers)
[2, 4, 6, 8, 10]
  • Sözlüklerde Kullanımı: Lambda fonksiyonları sözlüklerde kullanılabili ve her bir öğenin üzerinde işlem yapılabilir. Örneğin, "students" sözlüğünde tüm isimlerin sadece ilk harflerini büyük harfe dönüştürmek istediğimizde:
Kod Örneği: Çıktı:
students = {"john": 25, "amy": 30, "murat": 28}    cap_names = list(map(lambda x: x.capitalize(), students.keys()))    print(cap_names)
["John", "Amy", "Murat"]

Bu örnekler, lambda fonksiyonlarının programlama dilinde ne kadar pratik ve hızlı olduğunu göstermektedir. Ancak, özellikle daha büyük ve karmaşık işlemler için standart fonksiyon kullanımını tercih etmek daha doğru olabilir.


Sıralama Fonksiyonları (Sorting Functions)

Python'da sıralama işlemleri yapmak için kullanılan sorted() fonksiyonu, listeleri sıralamak için kullanılır. Sıralama işlemi, verileri önceden belirlenen bir kurala göre listelemeyi sağlar. Bu kurala göre büyükten küçüğe, küçükten büyüğe veya başka bir prensibe göre sıralama yapılabilir.

sorted() fonksiyonu, bir dizi argümanı alır ve bir liste döndürür. Örnek olarak, bir sayı listesi sıralanırsa, listenin başındaki sayılar küçükten büyüğe doğru sıralanır.

Kod Örneği: Açıklama:
numbers = [3, 7, 1, 9, 12, 4]sorted_numbers = sorted(numbers)print(sorted_numbers)
Bu kod örneği, numbers listesini sıralar ve sıralanmış listeyi sorted_numbers değişkenine atar. Daha sonra, sıralanmış sayıları ekrana yazdırır.
Çıktı:
[1, 3, 4, 7, 9, 12]

sorted() fonksiyonu, verilerin sıralanma yöntemini belirlemede flexibillik sağlar. Özelleştirilmiş bir sıralama fonksiyonu sağlayarak, karmaşık bir sıralama yöntemi belirlenebilir.

Örneğin, bir liste içindeki sözcükleri kendi içinde sıralamak için, sorted() fonksiyonuna bir ikinci argüman olarak bir lambda fonksiyonu sağlayarak, sözcükleri uzunluklarına göre sıralayabiliriz.

Kod Örneği: Açıklama:
words = ['apple', 'banana', 'cherry', 'date']sorted_words = sorted(words, key= lambda word: len(word))print(sorted_words)
Bu kod örneği, words listesindeki sözcükleri sıralar ve sıralama, sözcük uzunluğu temel alınarak yapılır. Daha sonra, sıralanmış sözcükleri ekrana yazdırır.
Çıktı:
['date', 'apple', 'banana', 'cherry']

Sıralama fonksiyonları, Python'da fonksiyonel programlama yaklaşımını kullanırken oldukça faydalıdır.

Sıralama fonksiyonları ile ilgili daha fazla bilgi için, Python belgelerinde ve çeşitli kaynaklarda mevcut olan kılavuzlar incelenebilir.


Map, Filter, ve Reduce Fonksiyonları

Fonksiyonel programlamada, map(), filter() ve reduce() fonksiyonları oldukça önemlidir. Bu fonksiyonlar, Python'da listelerle veya diğer iterable nesnelerle çalışır ve oldukça kullanışlıdır.

Map() fonksiyonu, belirli bir iterable nesne içindeki her öğe için aynı işlemi uygular ve sonuçları yeni bir liste olarak döndürür. Örneğin, aşağıdaki kod, listedeki her sayının karesini alır:

Örnek Kod Çıktı
sayilar = [1, 2, 3, 4, 5]  kareler = list(map(lambda x: x**2, sayilar))  print(kareler)
[1, 4, 9, 16, 25]

Filter() fonksiyonu, belirli bir iterable nesne içindeki öğeleri belirli bir koşulu sağlayanlardan oluşan yeni bir liste olarak döndürür. Örneğin, aşağıdaki kod, listedeki her çift sayıyı seçer:

Örnek Kod Çıktı
sayilar = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  ciftler = list(filter(lambda x: x%2 == 0, sayilar))  print(ciftler)
[2, 4, 6, 8, 10]

Reduce() fonksiyonu, iterable nesnelerdeki öğeleri belirli bir işleme tabi tutar ve sonuç olarak tek bir değer döndürür. Örneğin, aşağıdaki kod, sayıların toplamını bulur:

Örnek Kod Çıktı
from functools import reduce  sayilar = [1, 2, 3, 4, 5]  toplam = reduce(lambda x, y: x + y, sayilar)  print(toplam)
15

Map(), filter() ve reduce() fonksiyonlarının bir arada kullanımı da oldukça yaygındır. Bu fonksiyonlar, birçok işlemi daha kısa ve daha anlaşılır hale getirebilir ve kod tekrarını azaltabilir.


Dekoratörler ve Fonksiyonel Programlama

Fonksiyonel programlama, kodların daha okunaklı ve basitleştirilmiş bir şekilde yazılmasını sağlar. Bu programlama yaklaşımı ile birlikte, dekoratörler fonksiyonların daha da geliştirilmesini ve yeniden kullanılmasını sağlar.

Dekoratörler, fonksiyonlara eklenen ve bu fonksiyonların işlevselliğini genişleten özelliklerdir. Bu özellikler, fonksiyonların kullanım alanını genişletirken aynı zamanda kodlama sürecini de kolaylaştırır.

Örneğin, bir dekoratör fonksiyonu, bir fonksiyonun çalışması için öncesinde veya sonrasında bazı ayarlamalar yapabilir. Bunun yanı sıra, dekoratör fonksiyonlar, zaman zaman kodlama sürecinde ortaya çıkan bazı hataların da kolay tespit edilmesini sağlar.

Fonksiyonel programlama kavramları ile birlikte, dekoratörler de yazılan kodların daha efektif ve hızlı bir şekilde değerlendirilmesi için olmazsa olmaz bir unsur olarak karşımıza çıkar. Yalnızca kullanımı ile değil aynı zamanda fonksiyonel programlama yöntemiyle birleştiğinde, daha da etkili bir kullanıma sahip olur.

Özetlemek gerekirse, fonksiyonel programlama dekoratörlerinin kullanımı, kodlama sürecinde yapılan ayarlamaların basitleştirilmesini, hataların kolay tespit edilmesini ve fonksiyonların yeniden kullanılmasını sağlar. Bu nedenle, fonksiyonel programlama kavramları ile birlikte dekoratörlerin kullanılması, yazılımcıların kodları daha hızlı ve verimli bir şekilde yazmalarına yardımcı olur.


Decorator Factory Fonksiyonları

Decorator Factory Fonksiyonları, yeni bir dekoratör oluşturmak için kullanılan bir fonksiyonlardır. Bu fonksiyonlar, var olan bir dekoratörü özelleştirmek için kullanılabilir. Böylece, ihtiyaca göre farklı özelliklere sahip dekoratörler oluşturulabilir.

Birkaç örnek ile Decorator Factory Fonksiyonların kullanımını daha net hale getirebiliriz. Örneğin, bir restoran uygulaması geliştiriyor olalım ve menüdeki yemeklerin fiyatlarını indirim uygulayarak ödeme sürecinde hesaplamak istiyoruz. Bunun için, bir dekoratör oluşturabiliriz:

Kod: Çıktı:
@discount(0.1)def calculate_price(menu_items):    total_price = sum([item.price for item in menu_items])    return total_price
calculate_price([item1, item2, item3])# Output: 90

Yukarıdaki örnekte, discount() dekoratörü bir Decorator Factory Fonksiyonudur ve %10'luk bir indirim uygulamak için kullanılmıştır. Olası başka bir senaryoda, farklı bir indirim oranı gerektiğinde, aynı dekoratörü kullanarak, yeni bir dekoratör oluşturmak mümkündür:

Kod: Çıktı:
@discount(0.15)def calculate_price(menu_items):    total_price = sum([item.price for item in menu_items])    return total_price
calculate_price([item1, item2, item3])# Output: 85.5

Decorator Factory Fonksiyonları, Python'da fonksiyonel programlama prensiplerini kullanmanın en iyi yollarından biridir. Bu fonksiyonların esnek kullanımı, kodlama deneyimini daha verimli hale getirir ve aynı zamanda yeniden kullanılabilir kod blokları tasarlamaya yardımcı olur.


Generator Fonksiyonları

Python'da generator fonksiyonları, bellek verimliliği ve daha hızlı çalışma süresi için kullanılır. Generator fonksiyonları, normal bir fonksiyon gibi çalışır, ancak yield ifadesi kullanarak sonuçları verir. Yield ifadesi, fonksiyonun durduğu noktayı işaret eder ve sonuçları geri dönmeden önce çalışmayı askıya alır. Bu sayede, generator fonksiyonları, bir liste gerektirmeden, tek tek sonuçlar vererek bellek verimliliği sağlar.

Bu işlevler, iteratif döngülerde kullanılabilir. İteratif döngüler, belirli bir işlemi belirli bir sayıda kez tekrarlayan döngülerdir. Generator fonksiyonları, bellek tüketimini azaltır ve performansı arttırır.

Generator fonksiyonlarının kullanımı aşağıdaki örnekte verilmiştir:

Kod Örneği Açıklama
def sayilar(n):  for i in range(n):    yield inums = sayilar(5)print(next(nums))print(next(nums))print(next(nums))print(next(nums))print(next(nums))
Bu örnek, sayilar adlı bir generator fonksiyon tanımlar. Fonksiyon, n sayısına kadar bir dizi sayıyı üretir ve her bir sayıyı yield ifadesiyle geri döndürür. Generator fonksiyonu, for döngüsü içinde kullanılır ve for döngüsü, listeden bir sonraki öğeyi almak için her bir yield satırını kullanır.

Generatörün avantajı, tüm verileri tek seferde belleğe yüklemek zorunda kalmadan büyük veri kümeleri üzerinde döngü yapılabileceği gerçeğidir. Eğer bir veri kümesindeki her bir öğe üzerinde bir işlem yaparken bellek yüklememiz gerekirse, generatorler bellek verimliliği sağlar ve belleğin verilen sınırları içinde kalmasını sağlar.


Generator vs List Comprehension

Generator ve List Comprehension, fonksiyonel programlama yaklaşımının en iyi örneklerinden biridir. İkisi de veri setleri üzerinde işlem yapmayı sağlar, ancak bunu farklı yollarla yaparlar.

List Comprehension, bir liste oluşturmak için bir iterable (tekrarlanabilir) nesne üzerinde döngü yapar ve daha sonra bu döngü sonucunu yeni bir liste olarak kaydeder. List Comprehension, kodun okunaklılığını artırır ve sıfırdan bir liste oluşumundan daha hızlıdır. Ancak, bir liste oluşturulduktan sonra belleğin kaydedilmesi gereklidir ve büyük veri kümelerinde performans sorunlarına neden olabilir.

Generator fonksiyonlarıysa bellekte tutulmaz ve ihtiyaç duyulduğunda tek bir eleman üretir. Generators 'yield' ifadesi kullanarak değerleri itere eder ve bellek kullanımının verimliliği sağlar. Bununla birlikte, her attığınızda çalıştıkları için performans açısından daha yavaş olabilirler.

List Comprehension Generator
Oluşturulan listenin bellekte tutulması gereklidir Veriler bellekte tutulmaz
Hızlı olabilir Performans açısından yavaş çalışabilir
Okunaklılığı arttırır Okunaklılığı düşürebilir

Generator ve List Comprehension, Python'da fonksiyonel programlama stillerinden bazılarıdır. Doğru kullanıldığında, bu stiller kodun performansını ve okunaklılığını artırabilir. Hangi yöntemin kullanılması gerektiğine karar verirken veri setinin boyutunu ve amacını göz önünde bulundurmak önemlidir.