forked from yazbel/python-istihza
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathileri_fonksiyonlar.html
2205 lines (2076 loc) · 214 KB
/
ileri_fonksiyonlar.html
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="tr">
<html lang="tr">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta content="Bu bölümde fonksiyonlar konusunu inceleyeceğiz." name="description" />
<meta content="python, fonksiyon, lambda, recursive, decorator, closure, özyinelemeli, bezeyiciler, kapalı fonksiyonlar , nested , nonlocal , nested function , iç , iç içe , iç içe fonksiyonlar, generator, üreteç , yield , iterate , iterator" name="keywords" />
<title>İleri Düzey Fonksiyonlar — Python 3 için Türkçe Kılavuz</title>
<link rel="stylesheet" href="_static/pyramid.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/language_data.js"></script>
<script src="_static/translations.js"></script>
<link rel="search" title="Ara" href="search.html" />
<link rel="next" title="Modüller" href="moduller.html" />
<link rel="prev" title="Gömülü Fonksiyonlar" href="gomulu_fonksiyonlar.html" />
<!--[if lte IE 6]>
<link rel="stylesheet" href="_static/ie6.css" type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head><body>
<div class='header'><a href='https://yazbel.com'>yazbel.com</a></div>
<ul class='navbar'>
<li><a href="#"><del>pdf desteği sonlanmıştır</del></a></li>
<li class="forum"><a href="http://forum.yazbel.com">forum</a></li>
</ul>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Gezinti</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="moduller.html" title="Modüller"
accesskey="N">sonraki</a></li>
<li class="right" >
<a href="gomulu_fonksiyonlar.html" title="Gömülü Fonksiyonlar"
accesskey="P">önceki</a> |</li>
<li class="nav-item nav-item-0"><a href=".">⌂</a></li>
<li class="nav-item nav-item-this"><a href="">İleri Düzey Fonksiyonlar</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="body" role="main">
<div class="section" id="ileri-duzey-fonksiyonlar">
<h1>İleri Düzey Fonksiyonlar<a class="headerlink" href="#ileri-duzey-fonksiyonlar" title="Bu başlık için kalıcı bağlantı">¶</a></h1>
<p>Buraya gelinceye kadar fonksiyonlara ilişkin epey söz söyledik. Artık Python
programlama dilinde fonksiyonlara dair hemen her şeyi bildiğimizi rahatlıkla
söyleyebiliriz. Zira bu noktaya kadar hem fonksiyonların temel (ve orta düzey)
özelliklerini öğrendik, hem de ‘gömülü fonksiyon’ kavramını ve gömülü
fonksiyonların kendisini bütün ayrıntılarıyla inceledik. Dolayısıyla yazdığımız
kodlarda fonksiyonları oldukça verimli bir şekilde kullanabilecek kadar
fonksiyon bilgisine sahibiz artık.</p>
<p>Dediğimiz gibi, fonksiyonlara ilişkin en temel bilgileri edindik. Ancak
fonksiyonlara dair henüz bilmediğimiz şeyler de var. Ama artık Python
programlama dilinde geldiğimiz aşamayı dikkate alarak ileriye doğru bir adım
daha atabilir, fonksiyonlara dair ileri düzey sayılabilecek konulardan da söz
edebiliriz.</p>
<p>İlk olarak ‘lambda fonksiyonlarını’ ele alalım.</p>
<div class="section" id="lambda-fonksiyonlari">
<h2>Lambda Fonksiyonları<a class="headerlink" href="#lambda-fonksiyonlari" title="Bu başlık için kalıcı bağlantı">¶</a></h2>
<p>Şimdiye kadar Python programlama dilinde fonksiyon tanımlamak için hep <cite>def</cite>
adlı bir ifadeden yararlanmıştık. Bu bölümde ise Python programlama dilinde
fonksiyon tanımlamamızı sağlayacak, tıpkı <cite>def</cite> gibi bir ifadeden daha söz
edeceğiz. Fonksiyon tanımlamamızı sağlayan bu yeni ifadeye <cite>lambda</cite> denir. Bu
ifade ile oluşturulan fonksiyonlara ise ‘lambda fonksiyonları’…</p>
<p>Bildiğiniz gibi Python’da bir fonksiyonu <cite>def</cite> ifadesi yardımıyla şöyle
tanımlıyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">def</span> <span class="nf">fonk</span><span class="p">(</span><span class="n">param1</span><span class="p">,</span> <span class="n">param2</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">return</span> <span class="n">param1</span> <span class="o">+</span> <span class="n">param2</span>
</pre></div>
</div>
<p>Bu fonksiyon, kendisine verilen parametreleri birbiriyle toplayıp bize bunların
toplamını döndürüyor:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">fonk</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span>
<span class="go">6</span>
</pre></div>
</div>
<p>Peki aynı işlemi lambda fonksiyonları yardımıyla yapmak istersek nasıl bir yol
izleyeceğiz?</p>
<p>Dikkatlice bakın:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">fonk</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">param1</span><span class="p">,</span> <span class="n">param2</span><span class="p">:</span> <span class="n">param1</span> <span class="o">+</span> <span class="n">param2</span>
</pre></div>
</div>
<p>İşte burada tanımladığımız şey bir lambda fonksiyonudur. Bu lambda fonksiyonunu
da tıpkı biraz önce tanımladığımız def fonksiyonu gibi kullanabiliriz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">fonk</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span>
<span class="go">6</span>
</pre></div>
</div>
<p>Gördüğünüz gibi lambda fonksiyonlarını tanımlamak ve kullanmak hiç de zor değil.</p>
<p>Lambda fonksiyonlarının neye benzediğinden temel olarak bahsettiğimize göre
artık biraz daha derine inebiliriz.</p>
<p>Lambda fonksiyonları Python programlama dilinin ileri düzey fonksiyonlarından
biridir. Yukarıdaki örnek yardımıyla bu lambda fonksiyonlarının nasıl bir şey
olduğunu gördük. Esasında biz buraya gelene kadar bu lambda fonksiyonlarını hiç
görmemiş de değiliz. Hatırlarsanız daha önceki derslerimizde şöyle bir örnek kod
yazmıştık:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">harfler</span> <span class="o">=</span> <span class="s2">"abcçdefgğhıijklmnoöprsştuüvyz"</span>
<span class="n">çevrim</span> <span class="o">=</span> <span class="p">{</span><span class="n">i</span><span class="p">:</span> <span class="n">harfler</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">harfler</span><span class="p">}</span>
<span class="n">isimler</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"ahmet"</span><span class="p">,</span> <span class="s2">"ışık"</span><span class="p">,</span> <span class="s2">"ismail"</span><span class="p">,</span> <span class="s2">"çiğdem"</span><span class="p">,</span>
<span class="s2">"can"</span><span class="p">,</span> <span class="s2">"şule"</span><span class="p">,</span> <span class="s2">"iskender"</span><span class="p">]</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">isimler</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">çevrim</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">])))</span>
</pre></div>
</div>
<p>Burada <code class="docutils literal notranslate"><span class="pre">sorted()</span></code> fonksiyonunun <cite>key</cite> parametresi içinde kullandığımız ifade
bir lambda fonksiyonudur:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">çevrim</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
</pre></div>
</div>
<p>Peki lambda fonksiyonları nedir ve ne işe yarar?</p>
<p>Lambda fonksiyonlarını, bir fonksiyonun işlevselliğine ihtiyaç duyduğumuz, ama
konum olarak bir fonksiyon tanımlayamayacağımız veya fonksiyon tanımlamanın zor
ya da meşakkatli olduğu durumlarda kullanabiliriz. Yukarıdaki örnek kod, bu
tanıma iyi bir örnektir: <code class="docutils literal notranslate"><span class="pre">sorted()</span></code> fonksiyonunun <cite>key</cite> parametresi bizden bir
fonksiyon tanımı bekler. Ancak biz elbette oraya <cite>def</cite> ifadesini kullanarak
doğrudan bir fonksiyon tanımlayamayız. Ama <cite>def</cite> yerine <cite>lambda</cite> ifadesi
yardımıyla <cite>key</cite> parametresi için bir lambda fonksiyonu tanımlayabiliriz.</p>
<p>Eğer yukarıdaki kodları ‘normal’ bir fonksiyonla yazmak isteseydik şu kodları
kullanabilirdik:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">harfler</span> <span class="o">=</span> <span class="s2">"abcçdefgğhıijklmnoöprsştuüvyz"</span>
<span class="n">çevrim</span> <span class="o">=</span> <span class="p">{</span><span class="n">i</span><span class="p">:</span> <span class="n">harfler</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">harfler</span><span class="p">}</span>
<span class="n">isimler</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"ahmet"</span><span class="p">,</span> <span class="s2">"ışık"</span><span class="p">,</span> <span class="s2">"ismail"</span><span class="p">,</span> <span class="s2">"çiğdem"</span><span class="p">,</span>
<span class="s2">"can"</span><span class="p">,</span> <span class="s2">"şule"</span><span class="p">,</span> <span class="s2">"iskender"</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">sırala</span><span class="p">(</span><span class="n">eleman</span><span class="p">):</span>
<span class="k">return</span> <span class="n">çevrim</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">eleman</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">isimler</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">sırala</span><span class="p">))</span>
</pre></div>
</div>
<p>Burada lambda fonksiyonu kullanmak yerine, <code class="docutils literal notranslate"><span class="pre">sırala()</span></code> adlı bir fonksiyon
kullandık.</p>
<p>Eğer yukarıda ‘lambda’ ile yazdığımız örneği <code class="docutils literal notranslate"><span class="pre">sırala()</span></code> fonksiyonu ile
yazdığımız örnekle kıyaslarsanız lambda fonksiyonlarında hangi parçanın neye
karşılık geldiğini veya ne anlama sahip olduğunu rahatlıkla anlayabilirsiniz.</p>
<p>Gelin bir örnek daha verelim:</p>
<p>Diyelim ki bir sayının çift sayı olup olmadığını denetleyen bir fonksiyon yazmak
istiyorsunuz. Bunun için şöyle bir fonksiyon tanımlayabileceğimizi
biliyorsunuz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">çift_mi</span><span class="p">(</span><span class="n">sayı</span><span class="p">):</span>
<span class="k">return</span> <span class="n">sayı</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span>
</pre></div>
</div>
<p>Eğer <code class="docutils literal notranslate"><span class="pre">çift_mi()</span></code> fonksiyonuna parametre olarak verilen bir sayı çift ise
fonksiyonumuz <cite>True</cite> çıktısı verecektir:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">çift_mi</span><span class="p">(</span><span class="mi">100</span><span class="p">))</span>
<span class="kc">True</span>
</pre></div>
</div>
<p>Aksi halde <cite>False</cite> çıktısı alırız:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">çift_mi</span><span class="p">(</span><span class="mi">99</span><span class="p">))</span>
<span class="kc">False</span>
</pre></div>
</div>
<p>İşte yukarıdaki etkiyi lambda fonksiyonları yardımıyla da elde edebiliriz.</p>
<p>Dikkatlice bakın:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">çift_mi</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">sayı</span><span class="p">:</span> <span class="n">sayı</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span>
<span class="gp">>>> </span><span class="n">çift_mi</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">>>> </span><span class="n">çift_mi</span><span class="p">(</span><span class="mi">99</span><span class="p">)</span>
<span class="go">False</span>
</pre></div>
</div>
<p>Başka bir örnek daha verelim. Diyelim ki bir liste içindeki bütün sayıların
karesini hesaplamak istiyoruz. Elimizdeki liste şu:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">l</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">23</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">6</span><span class="p">]</span>
</pre></div>
</div>
<p>Bu listedeki sayıların her birinin karesini hesaplamak için şöyle bir şey
yazabiliriz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">l</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="n">i</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>
<span class="go">4</span>
<span class="go">25</span>
<span class="go">100</span>
<span class="go">529</span>
<span class="go">9</span>
<span class="go">36</span>
</pre></div>
</div>
<p>Veya şöyle bir şey:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="p">[</span><span class="n">i</span><span class="o">**</span><span class="mi">2</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">l</span><span class="p">]</span>
<span class="go">[4, 25, 100, 529, 9, 36]</span>
</pre></div>
</div>
<p>Ya da <code class="docutils literal notranslate"><span class="pre">map()</span></code> fonksiyonuyla birlikte lambda’yı kullanarak şu kodu
yazabiliriz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="o">*</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">sayı</span><span class="p">:</span> <span class="n">sayı</span> <span class="o">**</span> <span class="mi">2</span><span class="p">,</span> <span class="n">l</span><span class="p">))</span>
<span class="go">4 25 100 529 9 36</span>
</pre></div>
</div>
<p>Son örnekte verdiğimiz lambda’lı kodu normal bir fonksiyon tanımlayarak şöyle
de yazabilirdik:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">def</span> <span class="nf">karesi</span><span class="p">(</span><span class="n">sayı</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">return</span> <span class="n">sayı</span> <span class="o">**</span> <span class="mi">2</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="o">*</span><span class="nb">map</span><span class="p">(</span><span class="n">karesi</span><span class="p">,</span> <span class="n">l</span><span class="p">))</span>
<span class="go">4 25 100 529 9 36</span>
</pre></div>
</div>
<p>Sözün özü, mesela şu kod:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">10</span>
</pre></div>
</div>
<p>Türkçede şu anlama gelir:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="s1">'x'</span> <span class="n">adlı</span> <span class="n">bir</span> <span class="n">parametre</span> <span class="n">alan</span> <span class="n">bir</span> <span class="k">lambda</span> <span class="n">fonksiyonu</span> <span class="n">tanımla</span><span class="o">.</span> <span class="n">Bu</span> <span class="n">fonksiyon</span><span class="p">,</span> <span class="n">bu</span>
<span class="s1">'x parametresine 10 sayısını eklesin.</span>
</pre></div>
</div>
<p>Biz yukarıdaki örneklerde lambda fonksiyonunu tek bir parametre ile tanımladık.
Ama elbette lambda fonksiyonlarının birden fazla parametre de alabileceğini de
biliyorsunuz.</p>
<p>Örneğin:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span> <span class="n">birleştir</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">ifade</span><span class="p">,</span> <span class="n">birleştirici</span><span class="p">:</span> <span class="n">birleştirici</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">ifade</span><span class="o">.</span><span class="n">split</span><span class="p">())</span>
</pre></div>
</div>
<p>Burada lambda fonksiyonumuz toplam iki farklı parametre alıyor: Bunlardan ilki
<cite>ifade</cite>, ikincisi ise <cite>birleştirici</cite>. Fonksiyonumuzun gövdesinde <cite>ifade</cite>
parametresine <code class="docutils literal notranslate"><span class="pre">split()</span></code> metodunu uyguladıktan sonra, elde ettiğimiz parçaları
<cite>birleştirici</cite> parametresinin değerini kullanarak birbirleriyle birleştiriyoruz.
Yani:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">birleştir</span><span class="p">(</span><span class="s1">'istanbul büyükşehir belediyesi'</span><span class="p">,</span> <span class="s1">'-'</span><span class="p">)</span>
<span class="go">'istanbul-büyükşehir-belediyesi'</span>
</pre></div>
</div>
<p>Eğer aynı işlevi ‘normal’ bir fonksiyon yardımıyla elde etmek isteseydik şöyle
bir şey yazabilirdik:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">def</span> <span class="nf">birleştir</span><span class="p">(</span><span class="n">ifade</span><span class="p">,</span> <span class="n">birleştirici</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">return</span> <span class="n">birleştirici</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">ifade</span><span class="o">.</span><span class="n">split</span><span class="p">())</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="n">birleştir</span><span class="p">(</span><span class="s1">'istanbul büyükşehir belediyesi'</span><span class="p">,</span> <span class="s1">'-'</span><span class="p">)</span>
<span class="go">'istanbul-büyükşehir-belediyesi'</span>
</pre></div>
</div>
<p>Yukarıdaki örneklerin dışında, lambda fonksiyonları özellikle grafik arayüz
çalışmaları yaparken işinize yarayabilir. Örneğin:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">tkinter</span>
<span class="kn">import</span> <span class="nn">tkinter.ttk</span> <span class="k">as</span> <span class="nn">ttk</span>
<span class="n">pen</span> <span class="o">=</span> <span class="n">tkinter</span><span class="o">.</span><span class="n">Tk</span><span class="p">()</span>
<span class="n">btn</span> <span class="o">=</span> <span class="n">ttk</span><span class="o">.</span><span class="n">Button</span><span class="p">(</span><span class="n">text</span><span class="o">=</span><span class="s1">'merhaba'</span><span class="p">,</span> <span class="n">command</span><span class="o">=</span><span class="k">lambda</span><span class="p">:</span> <span class="nb">print</span><span class="p">(</span><span class="s1">'merhaba'</span><span class="p">))</span>
<span class="n">btn</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="n">padx</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">pady</span><span class="o">=</span><span class="mi">20</span><span class="p">)</span>
<span class="n">pen</span><span class="o">.</span><span class="n">mainloop</span><span class="p">()</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Not</p>
<p>Bu kodlardan hiçbir şey anlamamış olabilirsiniz. Endişe etmeyin.
Burada amacımız size sadece lambda fonksiyonlarının kullanımını göstermek. Bu
kodlarda yalnızca lambda fonksiyonuna odaklanmanız şimdilik yeterli olacaktır.
Eğer bu kodları çalıştıramadıysanız <a class="reference external" href="https://forum.yazbel.com/">https://forum.yazbel.com/</a> adresinde
sorununuzu dile getirebilirsiniz.</p>
</div>
<p>Bu kodları çalıştırıp ‘merhaba’ düğmesine bastığınızda komut satırında ‘merhaba’
çıktısı görünecektir. Tkinter’de fonksiyonların <cite>command</cite> parametresi bizden
parametresiz bir fonksiyon girmemizi bekler. Ancak bazen, elde etmek istediğimiz
işlevsellik için oraya parametreli bir fonksiyon yazmak durumunda kalabiliriz.
İşte bunun gibi durumlarda lambda fonksiyonları faydalı olabilir. Elbette
yukarıdaki kodları şöyle de yazabilirdik:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">tkinter</span>
<span class="kn">import</span> <span class="nn">tkinter.ttk</span> <span class="k">as</span> <span class="nn">ttk</span>
<span class="n">pen</span> <span class="o">=</span> <span class="n">tkinter</span><span class="o">.</span><span class="n">Tk</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">merhaba</span><span class="p">():</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'merhaba'</span><span class="p">)</span>
<span class="n">btn</span> <span class="o">=</span> <span class="n">ttk</span><span class="o">.</span><span class="n">Button</span><span class="p">(</span><span class="n">text</span><span class="o">=</span><span class="s1">'merhaba'</span><span class="p">,</span> <span class="n">command</span><span class="o">=</span><span class="n">merhaba</span><span class="p">)</span>
<span class="n">btn</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="n">padx</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">pady</span><span class="o">=</span><span class="mi">20</span><span class="p">)</span>
<span class="n">pen</span><span class="o">.</span><span class="n">mainloop</span><span class="p">()</span>
</pre></div>
</div>
<p>Burada da lambda yerine isimli bir fonksiyon tanımlayıp, <cite>command</cite> parametresine
doğrudan bu fonksiyonu verdik.</p>
<p>Bütün bu örneklerden gördüğünüz gibi, lambda fonksiyonları son derece pratik
araçlardır. Normal, isimli fonksiyonlarla elde ettiğimiz işlevselliği, lambda
fonksiyonları yardımıyla çok daha kısa bir şekilde elde edebiliriz. Ancak lambda
fonksiyonları normal fonksiyonlara göre biraz daha okunaksız yapılardır. O
yüzden, eğer lambda fonksiyonlarını kullanmaya mecbur değilseniz, bunların
yerine normal fonksiyonları veya yerine göre liste üreteçlerini tercih
edebilirsiniz.</p>
</div>
<div class="section" id="ozyinelemeli-recursive-fonksiyonlar">
<h2>Özyinelemeli (<em>Recursive</em>) Fonksiyonlar<a class="headerlink" href="#ozyinelemeli-recursive-fonksiyonlar" title="Bu başlık için kalıcı bağlantı">¶</a></h2>
<p>Bu bölümde, lambda fonksiyonlarının ardından, yine Python’ın ileri düzey
konularından biri olan ‘özyinelemeli fonksiyonlar’dan söz edeceğiz. İngilizcede
<em>recursive functions</em> olarak adlandırılan özyinelemeli fonksiyonların, Python
programlama dilinin anlaması en zor konularından biri olduğu söylenir. Ama bu
söylenti sizi hiç endişelendirmesin. Zira biz burada bu çapraşık görünen konuyu
size olabildiğince basit ve anlaşılır bir şekilde sunmak için elimizden gelen
bütün çabayı göstereceğiz.</p>
<p>O halde hemen başlayalım…</p>
<p>Şimdiye kadar Python’da pek çok fonksiyon gördük. Bu fonksiyonlar kimi zaman
Python programcılarınca tanımlanıp dile entegre edilmiş ‘gömülü fonksiyonlar’
(<em>builtin functions</em>) olarak, kimi zamansa o anda içinde bulunduğumuz duruma ve
ihtiyaçlarımıza göre bizzat kendimizin tanımladığı ‘el yapımı fonksiyonlar’
(<em>custom functions</em>) olarak çıktı karşımıza.</p>
<p>Şimdiye kadar öğrendiğimiz bütün bu fonksiyonların ortak bir noktası vardı. Bu
ortak nokta, şu ana kadar fonksiyonları kullanarak yaptığımız örneklerden de
gördüğünüz gibi, bu fonksiyonlar yardımıyla başka fonksiyonları çağırabiliyor
olmamız. Örneğin:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">selamla</span><span class="p">(</span><span class="n">kim</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'merhaba'</span><span class="p">,</span> <span class="n">kim</span><span class="p">)</span>
</pre></div>
</div>
<p>Burada <code class="docutils literal notranslate"><span class="pre">selamla()</span></code> adlı bir fonksiyon tanımladık. Gördüğünüz gibi bu fonksiyon
<code class="docutils literal notranslate"><span class="pre">print()</span></code> adlı başka bir fonksiyonu çağırıyor. Burada sıradışı bir şey yok.
Dediğimiz gibi, şimdiye kadar zaten hep böyle fonksiyonlar görmüştük.</p>
<p>Python fonksiyonları, yukarıdaki örnekte de gördüğünüz gibi, nasıl başka
fonksiyonları çağırabiliyorsa, aynı şekilde, istenirse, kendi kendilerini de
çağırabilirler. İşte bu tür fonksiyonlara Python programlama dilinde ‘kendi
kendilerini yineleyen’, veya daha teknik bir dille ifade etmek gerekirse
‘özyinelemeli’ (<em>recursive</em>) fonksiyonlar adı verilir.</p>
<p>Çok basit bir örnek verelim. Diyelim ki, kendisine parametre olarak verilen bir
karakter dizisi içindeki karakterleri teker teker azaltarak ekrana basan bir
fonksiyon yazmak istiyorsunuz. Yani mesela elinizde ‘istihza’ adlı bir karakter
dizisi var. Sizin amacınız bu karakter dizisini şu şekilde basan bir fonksiyon
yazmak:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">istihza</span>
<span class="n">stihza</span>
<span class="n">tihza</span>
<span class="n">ihza</span>
<span class="n">hza</span>
<span class="n">za</span>
<span class="n">a</span>
</pre></div>
</div>
<p>Elbette bu işi yapacak bir fonksiyonu, daha önce öğrendiğiniz döngüler ve başka
yapılar yardımıyla rahatlıkla yazabilirsiniz. Ama isterseniz aynı işi
özyinelemeli fonksiyonlar yardımıyla da yapabilirsiniz.</p>
<p>Şimdi şu kodlara dikkatlice bakın:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="k">return</span> <span class="n">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="nb">print</span><span class="p">(</span><span class="n">azalt</span><span class="p">(</span><span class="s1">'istihza'</span><span class="p">))</span>
</pre></div>
</div>
<p>Bu kodlar bize yukarıda bahsettiğimiz çıktıyı verecek:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">istihza</span>
<span class="n">stihza</span>
<span class="n">tihza</span>
<span class="n">ihza</span>
<span class="n">hza</span>
<span class="n">za</span>
<span class="n">a</span>
</pre></div>
</div>
<p>Fonksiyonumuzu yazıp çalıştırdığımıza ve bu fonksiyonun bize nasıl bir çıktı
verdiğini gördüğümüze göre fonksiyonu açıklamaya geçebiliriz.</p>
<p>Bu fonksiyon ilk bakışta daha önce öğrendiğimiz fonksiyonlardan çok da farklı
görünmüyor aslında. Ama eğer fonksiyonun son kısmına bakacak olursanız, bu
fonksiyonu daha önce öğrendiğimiz fonksiyonlardan ayıran şu satırı görürsünüz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">return</span> <span class="n">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
</pre></div>
</div>
<p>Gördüğünüz gibi, burada <code class="docutils literal notranslate"><span class="pre">azalt()</span></code> fonksiyonu içinde yine <code class="docutils literal notranslate"><span class="pre">azalt()</span></code>
fonksiyonunu çağırıyoruz. Böylece fonksiyonumuz sürekli olarak kendi kendini
yineliyor. Yani aynı fonksiyonu tekrar tekrar uyguluyor.</p>
<p>Peki ama bunu nasıl yapıyor?</p>
<p>Nasıl bir durumla karşı karşıya olduğumuzu daha iyi anlamak için yukarıdaki
kodları şu şekilde yazalım:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">s</span><span class="p">))</span>
<span class="k">return</span> <span class="n">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
</pre></div>
</div>
<p>Burada fonksiyonun her yinelenişinde, özyinelemeli fonksiyona parametre olarak
giden karakter dizisinin nasıl değiştiğini birazcık daha net olarak görebilmek
için karakter dizisi içindeki karakterleri bir liste haline getirip ekrana
basıyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">s</span><span class="p">))</span>
</pre></div>
</div>
<p>Bu kodları çalıştırdığımızda şu çıktıyı alacağız:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'i'</span><span class="p">,</span> <span class="s1">'s'</span><span class="p">,</span> <span class="s1">'t'</span><span class="p">,</span> <span class="s1">'i'</span><span class="p">,</span> <span class="s1">'h'</span><span class="p">,</span> <span class="s1">'z'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">]</span>
<span class="p">[</span><span class="s1">'s'</span><span class="p">,</span> <span class="s1">'t'</span><span class="p">,</span> <span class="s1">'i'</span><span class="p">,</span> <span class="s1">'h'</span><span class="p">,</span> <span class="s1">'z'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">]</span>
<span class="p">[</span><span class="s1">'t'</span><span class="p">,</span> <span class="s1">'i'</span><span class="p">,</span> <span class="s1">'h'</span><span class="p">,</span> <span class="s1">'z'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">]</span>
<span class="p">[</span><span class="s1">'i'</span><span class="p">,</span> <span class="s1">'h'</span><span class="p">,</span> <span class="s1">'z'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">]</span>
<span class="p">[</span><span class="s1">'h'</span><span class="p">,</span> <span class="s1">'z'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">]</span>
<span class="p">[</span><span class="s1">'z'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">]</span>
<span class="p">[</span><span class="s1">'a'</span><span class="p">]</span>
</pre></div>
</div>
<p>Yukarıdaki çıktının ilk satırında gördüğünüz gibi, fonksiyon ilk çağrıldığında
listede ‘istihza’ karakter dizisini oluşturan bütün harfler var. Yani
fonksiyonumuz ilk çalışmada parametre olarak karakter dizisinin tamamını alıyor.
Ancak fonksiyonun her yinelenişinde listedeki harfler birer birer düşüyor.
Böylece özyinelemeli fonksiyonumuz parametre olarak karakter dizisinin her
defasında bir eksiltilmiş biçimini alıyor.</p>
<p>Yukarıdaki sözünü ettiğimiz düşmenin yönü karakter dizisinin başından sonuna
doğru. Yani her defasında, elde kalan karakter dizisinin ilk harfi düşüyor.
Düşme yönünün böyle olması bizim kodları yazış şeklimizden kaynaklanıyor. Eğer
bu kodları şöyle yazsaydık:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">s</span><span class="p">))</span>
<span class="k">return</span> <span class="n">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<p>Harflerin düşme yönü sondan başa doğru olacaktı:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'i'</span><span class="p">,</span> <span class="s1">'s'</span><span class="p">,</span> <span class="s1">'t'</span><span class="p">,</span> <span class="s1">'i'</span><span class="p">,</span> <span class="s1">'h'</span><span class="p">,</span> <span class="s1">'z'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">]</span>
<span class="p">[</span><span class="s1">'i'</span><span class="p">,</span> <span class="s1">'s'</span><span class="p">,</span> <span class="s1">'t'</span><span class="p">,</span> <span class="s1">'i'</span><span class="p">,</span> <span class="s1">'h'</span><span class="p">,</span> <span class="s1">'z'</span><span class="p">]</span>
<span class="p">[</span><span class="s1">'i'</span><span class="p">,</span> <span class="s1">'s'</span><span class="p">,</span> <span class="s1">'t'</span><span class="p">,</span> <span class="s1">'i'</span><span class="p">,</span> <span class="s1">'h'</span><span class="p">]</span>
<span class="p">[</span><span class="s1">'i'</span><span class="p">,</span> <span class="s1">'s'</span><span class="p">,</span> <span class="s1">'t'</span><span class="p">,</span> <span class="s1">'i'</span><span class="p">]</span>
<span class="p">[</span><span class="s1">'i'</span><span class="p">,</span> <span class="s1">'s'</span><span class="p">,</span> <span class="s1">'t'</span><span class="p">]</span>
<span class="p">[</span><span class="s1">'i'</span><span class="p">,</span> <span class="s1">'s'</span><span class="p">]</span>
<span class="p">[</span><span class="s1">'i'</span><span class="p">]</span>
</pre></div>
</div>
<p>Burada, bir önceki koddaki <code class="docutils literal notranslate"><span class="pre">azalt(s[1:])</span></code> satırını <code class="docutils literal notranslate"><span class="pre">azalt(s[:-1])</span></code> şeklinde
değiştirdiğimize dikkat edin.</p>
<p>Fonksiyonun nasıl işlediğini daha iyi anlamak için, ‘istihza’ karakter dizisinin
son harfinin her yineleniş esnasındaki konumunun nasıl değiştiğini de
izleyebilirsiniz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">n</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">def</span> <span class="nf">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="k">global</span> <span class="n">n</span>
<span class="n">mesaj</span> <span class="o">=</span> <span class="s1">'</span><span class="si">{}</span><span class="s1"> harfinin </span><span class="si">{}</span><span class="s1">. çalışmadaki konumu: </span><span class="si">{}</span><span class="s1">'</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">n</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="nb">print</span><span class="p">(</span><span class="n">mesaj</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="s1">'a'</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">s</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="s1">'a'</span><span class="p">)))</span>
<span class="k">return</span> <span class="n">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="n">azalt</span><span class="p">(</span><span class="s1">'istihza'</span><span class="p">)</span>
</pre></div>
</div>
<p>Bu kodlar şu çıktıyı verir:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="n">harfinin</span> <span class="mf">1.</span> <span class="n">çalışmadaki</span> <span class="n">konumu</span><span class="p">:</span> <span class="mi">6</span>
<span class="n">a</span> <span class="n">harfinin</span> <span class="mf">2.</span> <span class="n">çalışmadaki</span> <span class="n">konumu</span><span class="p">:</span> <span class="mi">5</span>
<span class="n">a</span> <span class="n">harfinin</span> <span class="mf">3.</span> <span class="n">çalışmadaki</span> <span class="n">konumu</span><span class="p">:</span> <span class="mi">4</span>
<span class="n">a</span> <span class="n">harfinin</span> <span class="mf">4.</span> <span class="n">çalışmadaki</span> <span class="n">konumu</span><span class="p">:</span> <span class="mi">3</span>
<span class="n">a</span> <span class="n">harfinin</span> <span class="mf">5.</span> <span class="n">çalışmadaki</span> <span class="n">konumu</span><span class="p">:</span> <span class="mi">2</span>
<span class="n">a</span> <span class="n">harfinin</span> <span class="mf">6.</span> <span class="n">çalışmadaki</span> <span class="n">konumu</span><span class="p">:</span> <span class="mi">1</span>
<span class="n">a</span> <span class="n">harfinin</span> <span class="mf">7.</span> <span class="n">çalışmadaki</span> <span class="n">konumu</span><span class="p">:</span> <span class="mi">0</span>
</pre></div>
</div>
<p>Gördüğünüz gibi ‘istihza’ kelimesinin en sonunda bulunan ‘a’ harfi her defasında
baş tarafa doğru ilerliyor.</p>
<p>Aynı şekilde, kodları daha iyi anlayabilmek için, fonksiyona parametre olarak
verdiğimiz ‘istihza’ kelimesinin her yinelemede ne kadar uzunluğa sahip olduğunu
da takip edebilirsiniz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">))</span>
<span class="k">return</span> <span class="n">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<p>Bu fonksiyonu ‘istihza’ karakter dizisine uyguladığımızda bize şu çıktıyı
veriyor:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="mi">7</span>
<span class="mi">6</span>
<span class="mi">5</span>
<span class="mi">4</span>
<span class="mi">3</span>
<span class="mi">2</span>
<span class="mi">1</span>
</pre></div>
</div>
<p>Gördüğünüz gibi, fonksiyonun kendini her yineleyişinde karakter dizimiz
küçülüyor.</p>
<p>Bu durum bize özyinelemeli fonksiyonlar hakkında çok önemli bir bilgi veriyor
esasında:</p>
<p>Özyinelemeli fonksiyonlar; büyük bir problemin çözülebilmesi için, o problemin,
problemin bütününü temsil eden daha küçük bir parçası üzerinde işlem
yapabilmemizi sağlayan fonksiyonlardır.</p>
<p>Yukarıdaki örnekte de bu ilkeyi uyguluyoruz. Yani biz ‘istihza’ karakter
dizisinin öncelikle yalnızca ilk karakterini düşürüyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
</pre></div>
</div>
<p>Daha sonra da bu yöntemi özyinelemeli bir şekilde uyguladığımızda, ‘istihza’
karakter dizisinin her defasında daha küçük bir parçası bu yöntemden
etkileniyor:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
</pre></div>
</div>
<p>Yani fonksiyonumuz ilk olarak ‘istihza’ karakter dizisinin ilk harfi olan ‘i’
harfini düşürüyor. Sonra ‘stihza’ kelimesinin ilk harfi olan ‘s’ harfini
düşürüyor. Ardından ‘tihza’ kelimesinin ilk harfi olan ‘t’ harfini düşürüyor ve
kelime tükenene kadar bu işlemi devam ettiriyor.</p>
<p>Peki ama bunu nasıl yapıyor?</p>
<p>Şimdi yukarıdaki fonksiyondaki şu kısma dikkatlice bakın:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span>
</pre></div>
</div>
<p>İşte burada özyinelemeli fonksiyonumuzun, karakter dizisi üzerinde ne kadar
derine inmesi gerektiğini belirliyoruz. Buna göre, karakter dizisinin uzunluğu
1’in altına düştüğünde eldeki karakter dizisini döndürüyoruz. Yani karakter
dizisinin uzunluğu 1’in altına düştüğünde elde kalan karakter dizisi boş bir
karakter dizisi olduğu için o boş karakter dizisini döndürüyoruz. Eğer istersek
elbette bu durumda başka bir şey de döndürebiliriz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="s1">'bitti!'</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="k">return</span> <span class="n">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
</pre></div>
</div>
<p>İşte <code class="docutils literal notranslate"><span class="pre">if</span> <span class="pre">len(s)</span> <span class="pre"><</span> <span class="pre">1:</span></code> bloğunun bulunduğu bu kodlara ‘dip nokta’ adı veriyoruz.
Fonksiyonumuzun yinelene yinelene (veya başka bir ifadeyle ‘dibe ine ine’)
geleceği en son nokta burasıdır. Eğer bu dip noktayı belirtmezsek fonksiyonumuz,
tıpkı dipsiz bir kuyuya düşmüş gibi, sürekli daha derine inmeye çalışacak,
sonunda da hata verecektir. Ne demek istediğimizi daha iyi anlamak için
kodlarımızı şöyle yazalım:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="k">return</span> <span class="n">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
</pre></div>
</div>
<p>Gördüğünüz gibi burada herhangi bir dip nokta belirtmedik. Bu kodları
çalıştırdığımızda Python bize şöyle bir hata mesajı verecek:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="ne">RuntimeError</span><span class="p">:</span> <span class="n">maximum</span> <span class="n">recursion</span> <span class="n">depth</span> <span class="n">exceeded</span>
</pre></div>
</div>
<p>Yani:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">ÇalışmaZamanıHatası</span><span class="p">:</span> <span class="n">Azami</span> <span class="n">özyineleme</span> <span class="n">derinliği</span> <span class="n">aşıldı</span>
</pre></div>
</div>
<p>Dediğimiz gibi, özyinelemeli fonksiyonlar her yinelenişte sorunun (yani üzerinde
işlem yapılan parametrenin) biraz daha derinine iner. Ancak bu derine inmenin de
bir sınırı vardır. Bu sınırın ne olduğunu şu kodlar yardımıyla
öğrenebilirsiniz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">sys</span>
<span class="gp">>>> </span><span class="n">sys</span><span class="o">.</span><span class="n">getrecursionlimit</span><span class="p">()</span>
</pre></div>
</div>
<p>İşte biz özyinelemeli fonksiyonlarımızda dip noktayı mutlaka belirterek,
Python’ın fonksiyonu yinelerken ne kadar derine inip nerede duracağını
belirlemiş oluyoruz.</p>
<p>Şimdi son kez, yukarıdaki örnek fonksiyonu, özyineleme mantığını çok daha iyi
anlamanızı sağlayacak bir şekilde yeniden yazacağız. Dikkatlice bakın:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'özyineleme sürecine girerken:'</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
<span class="n">azalt</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'özyineleme sürecinden çıkarken:'</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
<span class="n">azalt</span><span class="p">(</span><span class="s1">'istihza'</span><span class="p">)</span>
</pre></div>
</div>
<p>Burada, fonksiyon kendini yinelemeye başlamadan hemen önce bir <code class="docutils literal notranslate"><span class="pre">print()</span></code>
satırı yerleştirerek <cite>s</cite> değişkeninin durumunu takip ediyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="s1">'özyineleme sürecine girerken:'</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
</pre></div>
</div>
<p>Aynı işlemi bir de fonksiyonun kendini yinelemeye başlamasının hemen ardından
yapıyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="s1">'özyineleme sürecinden çıkarken:'</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
</pre></div>
</div>
<p>Yukarıdaki kodlar bize şu çıktıyı verecek:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">özyineleme</span> <span class="n">sürecine</span> <span class="n">girerken</span><span class="p">:</span> <span class="n">istihza</span>
<span class="n">özyineleme</span> <span class="n">sürecine</span> <span class="n">girerken</span><span class="p">:</span> <span class="n">stihza</span>
<span class="n">özyineleme</span> <span class="n">sürecine</span> <span class="n">girerken</span><span class="p">:</span> <span class="n">tihza</span>
<span class="n">özyineleme</span> <span class="n">sürecine</span> <span class="n">girerken</span><span class="p">:</span> <span class="n">ihza</span>
<span class="n">özyineleme</span> <span class="n">sürecine</span> <span class="n">girerken</span><span class="p">:</span> <span class="n">hza</span>
<span class="n">özyineleme</span> <span class="n">sürecine</span> <span class="n">girerken</span><span class="p">:</span> <span class="n">za</span>
<span class="n">özyineleme</span> <span class="n">sürecine</span> <span class="n">girerken</span><span class="p">:</span> <span class="n">a</span>
<span class="n">özyineleme</span> <span class="n">sürecinden</span> <span class="n">çıkarken</span><span class="p">:</span> <span class="n">a</span>
<span class="n">özyineleme</span> <span class="n">sürecinden</span> <span class="n">çıkarken</span><span class="p">:</span> <span class="n">za</span>
<span class="n">özyineleme</span> <span class="n">sürecinden</span> <span class="n">çıkarken</span><span class="p">:</span> <span class="n">hza</span>
<span class="n">özyineleme</span> <span class="n">sürecinden</span> <span class="n">çıkarken</span><span class="p">:</span> <span class="n">ihza</span>
<span class="n">özyineleme</span> <span class="n">sürecinden</span> <span class="n">çıkarken</span><span class="p">:</span> <span class="n">tihza</span>
<span class="n">özyineleme</span> <span class="n">sürecinden</span> <span class="n">çıkarken</span><span class="p">:</span> <span class="n">stihza</span>
<span class="n">özyineleme</span> <span class="n">sürecinden</span> <span class="n">çıkarken</span><span class="p">:</span> <span class="n">istihza</span>
</pre></div>
</div>
<p>Gördüğünüz gibi fonksiyon özyineleme sürecine girerken düşürdüğü her bir
karakteri, özyineleme sürecinden çıkarken yeniden döndürüyor. Bu, özyinelemeli
fonksiyonların önemli bir özelliğidir. Mesela bu özellikten yararlanarak şöyle
bir kod yazabilirsiniz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">ters_çevir</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">ters_çevir</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="nb">print</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">ters_çevir</span><span class="p">(</span><span class="s1">'istihza'</span><span class="p">)</span>
</pre></div>
</div>
<p>Yazdığımız bu kodda <code class="docutils literal notranslate"><span class="pre">ters_çevir()</span></code> fonksiyonu, kendisine verilen parametreyi
ters çevirecektir. Yani yukarıdaki kod bize şu çıktıyı verir:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">a</span>
<span class="n">z</span>
<span class="n">h</span>
<span class="n">i</span>
<span class="n">t</span>
<span class="n">s</span>
<span class="n">i</span>
</pre></div>
</div>
<p>Burada yaptığımız şey çok basit: Yukarıda da söylediğimiz gibi, özyinelemeli
fonksiyonlar, özyineleme sürecine girerken yaptığı işi, özyineleme sürecinden
çıkarken tersine çevirir. İşte biz de bu özellikten yararlandık. Fonksiyonun
kendini yinelediği noktanın çıkışına bir <code class="docutils literal notranslate"><span class="pre">print()</span></code> fonksiyonu yerleştirip,
geri dönen karakterlerin ilk harfini ekrana bastık. Böylece <cite>s</cite> adlı
parametrenin tersini elde etmiş olduk.</p>
<p>Ancak eğer yukarıdaki kodları bu şekilde yazarsak, fonksiyondan dönen değeri her
yerde kullanamayız. Mesela yukarıdaki fonksiyonu aşağıdaki gibi kullanamayız:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">ters_çevir</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">ters_çevir</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="nb">print</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">kelime</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s1">'kelime girin: '</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Girdiğiniz kelimenin tersi: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">kelime</span><span class="p">)</span>
</pre></div>
</div>
<p>Fonksiyonumuzun daha kullanışlı olabilmesi için kodlarımızı şöyle yazabiliriz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">ters_çevir</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">ters_çevir</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span> <span class="o">+</span> <span class="n">s</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">kelime</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s1">'kelime girin: '</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Girdiğiniz kelimenin tersi: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">ters_çevir</span><span class="p">(</span><span class="n">kelime</span><span class="p">)))</span>
</pre></div>
</div>
<p>Burada bizim amacımızı gerçekleştirmemizi sağlayan satır şu:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">return</span> <span class="n">ters_çevir</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span> <span class="o">+</span> <span class="n">s</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</pre></div>
</div>
<p>İlk bakışta bu satırın nasıl çalıştığını anlamak zor gelebilir. Ama aslında son
derece basit bir mantığı var bu kodların. Şöyle düşünün: <code class="docutils literal notranslate"><span class="pre">ters_çevir()</span></code>
fonksiyonunu özyinelemeli olarak işlettiğimizde, yani şu kodu yazdığımızda:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">return</span> <span class="n">ters_çevir</span><span class="p">(</span><span class="n">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
</pre></div>
</div>
<p>…döndürülecek son değer boş bir karakter dizisidir. İşte biz özyinelemeden
çıkılırken geri dönen karakterlerin ilk harflerini bu boş karakter dizisine
ekliyoruz ve böylece girdiğimiz karakter dizisinin ters halini elde etmiş
oluyoruz.</p>
<p>Yukarıdaki işlevin aynısını, özyinelemeli fonksiyonunuzu şöyle yazarak da elde
edebilirdiniz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">ters_çevir</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">ters_çevir</span><span class="p">(</span><span class="n">s</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="nb">print</span><span class="p">(</span><span class="n">ters_çevir</span><span class="p">(</span><span class="s1">'istihza'</span><span class="p">))</span>
</pre></div>
</div>
<p>Burada aynı iş için farklı bir yaklaşım benimsedik. İlk olarak, dip noktasını şu
şekilde belirledik:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span>
</pre></div>
</div>
<p>Bildiğiniz gibi, boş veri tiplerinin bool değeri <code class="docutils literal notranslate"><span class="pre">False</span></code>’tur. Dolayısıyla
özyineleme sırasında <cite>s</cite> parametresinin uzunluğunun 1’in altına düşmesi, <cite>s</cite>
parametresinin içinin boşaldığını gösterir. Yani o anda <cite>s</cite> parametresinin bool
değeri <code class="docutils literal notranslate"><span class="pre">False</span></code> olur. Biz de yukarıda bu durumdan faydalandık.</p>
<p>Bir önceki kodlara göre bir başka farklılık da şu satırda:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">return</span> <span class="n">s</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">ters_çevir</span><span class="p">(</span><span class="n">s</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<p>Burada benimsediğimiz yaklaşımın özü şu: Bildiğiniz gibi bir karakter dizisini
ters çevirmek istediğimizde öncelikle bu karakter dizisinin en son karakterini
alıp en başa yerleştiririz. Yani mesela elimizdeki karakter dizisi ‘istihza’
ise, bu karakter dizisini ters çevirmenin ilk adımı bunun en son karakteri olan
‘a’ harfini alıp en başa koymaktır. Daha sonra da geri kalan harfleri tek tek
tersten buna ekleriz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">düz</span><span class="p">:</span> <span class="n">istihza</span>
<span class="n">ters</span><span class="p">:</span> <span class="n">a</span> <span class="o">+</span> <span class="n">z</span> <span class="o">+</span> <span class="n">h</span> <span class="o">+</span> <span class="n">i</span> <span class="o">+</span> <span class="n">t</span> <span class="o">+</span> <span class="n">s</span> <span class="o">+</span> <span class="n">i</span>
</pre></div>
</div>
<p>İşte yukarıdaki fonksiyonda da yaptığımız şey tam anlamıyla budur.</p>
<p>Önce karakter dizisinin son harfini en başa koyuyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">return</span> <span class="n">s</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</pre></div>
</div>
<p>Ardından da buna geri kalan harfleri tek tek tersten ekliyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">return</span> <span class="n">s</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">ters_çevir</span><span class="p">(</span><span class="n">s</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<p>Özyinelemeli fonksiyonlara ilişkin olarak yukarıda tek bir örnek üzerinde epey
açıklama yaptık. Bu örnek ve açıklamalar, özyinelemeli fonksiyonların nasıl
çalıştığı konusunda size epey fikir vermiş olmalı. Ancak elbette bu
fonksiyonları tek bir örnek yardımıyla tamamen anlayamamış olabilirsiniz. O
yüzden gelin isterseniz bir örnek daha verelim. Mesela bu kez de basit bir sayaç
yapalım:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sayaç</span><span class="p">(</span><span class="n">sayı</span><span class="p">,</span> <span class="n">sınır</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sayı</span><span class="p">)</span>
<span class="k">if</span> <span class="n">sayı</span> <span class="o">==</span> <span class="n">sınır</span><span class="p">:</span>
<span class="k">return</span> <span class="s1">'bitti!'</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">sayaç</span><span class="p">(</span><span class="n">sayı</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">sınır</span><span class="p">)</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Not</p>
<p>Bu fonksiyonun yaptığı işi elbette başka şekillerde çok daha kolay bir
şekilde halledebilirdik. Bu örneği burada vermemizin amacı yalnızca özyinelemeli
fonksiyonların nasıl işlediğini göstermek. Yoksa böyle bir işi özyinelemeli
fonksiyonlarla yapmanızı beklemiyoruz.</p>
</div>
<p>Yukarıdaki fonksiyona dikkatlice bakarsanız aslında yaptığı işi çok basit bir
şekilde gerçekleştirdiğini göreceksiniz.</p>
<p>Burada öncelikle <code class="docutils literal notranslate"><span class="pre">sayaç()</span></code> adlı bir fonksiyon tanımladık. Bu fonksiyon toplam
iki farklı parametre alıyor: <cite>sayı</cite> ve <cite>sınır</cite>.</p>
<p>Buna göre fonksiyonumuzu şöyle kullanıyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">sayaç</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">100</span><span class="p">))</span>
</pre></div>
</div>
<p>Burada <cite>sayı</cite> parametresine verdiğimiz <cite>0</cite> değeri sayacımızın saymaya kaçtan
başlayacağını gösteriyor. <cite>sınır</cite> parametresine verdiğimiz <cite>100</cite> değeri ise kaça
kadar sayılacağını gösteriyor. Buna göre biz <cite>0</cite>’dan <cite>100</cite>’e kadar olan sayıları
sayıyoruz…</p>
<p>Gelin şimdi biraz fonksiyonumuzu inceleyelim.</p>
<p>İlk olarak şu satırı görüyoruz fonksiyon gövdesinde:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">sayı</span><span class="p">)</span>
</pre></div>
</div>
<p>Bu satır, özyinelemeli fonksiyonun her yinelenişinde <cite>sayı</cite> parametresinin
durumunu ekrana basacak.</p>
<p>Sonraki iki satırda ise şu kodları görüyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">sayı</span> <span class="o">==</span> <span class="n">sınır</span><span class="p">:</span>
<span class="k">return</span> <span class="s1">'bitti!'</span>
</pre></div>
</div>
<p>Bu bizim ‘dip nokta’ adını verdiğimiz şey. Fonksiyonumuz yalnızca bu noktaya
kadar yineleyecek, bu noktanın ilerisine geçmeyecektir. Yani <cite>sayı</cite>
parametresinin değeri <cite>sınır</cite> parametresinin değerine ulaştığında özyineleme
işlemi de sona erecek. Eğer böyle bir dip nokta belirtmezsek fonksiyonumuz
sonsuza kadar kendini yinelemeye çalışacak, daha önce sözünü ettiğimiz
‘özyineleme limiti’ nedeniyle de belli bir aşamadan sonra hata verip çökecektir.</p>
<p>Sonraki satırlarda ise şu kodları görüyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">sayaç</span><span class="p">(</span><span class="n">sayı</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">sınır</span><span class="p">)</span>
</pre></div>
</div>
<p>Bu satırlar, bir önceki aşamada belirttiğimiz dip noktaya ulaşılana kadar
fonksiyonumuzun hangi işlemleri yapacağını gösteriyor. Buna göre, fonksiyonun
her yinelenişinde <cite>sayı</cite> parametresinin değerini 1 sayı artırıyoruz.</p>
<p>Fonksiyonumuzu <code class="docutils literal notranslate"><span class="pre">sayaç(0,</span> <span class="pre">100)</span></code> gibi bir komutla çalıştırdığımızı düşünürsek,
fonksiyonun ilk çalışmasında <cite>0</cite> olan sayı değeri sonraki yinelemede <cite>1</cite>,
sonraki yinelemede <cite>2</cite>, sonraki yinelemede ise <cite>3</cite> olacak ve bu durum <cite>sınır</cite>
değer olan <cite>100</cite>’e varılana kadar devam edecektir. <cite>sayı</cite> parametresinin değeri
<cite>100</cite> olduğunda ise dip nokta olarak verdiğimiz ölçüt devreye girecek ve
fonksiyonun kendi kendisini yinelemesi işlemine son verilecektir.</p>
<p>Biz yukarıdaki örnekte yukarıya doğru sayan bir fonksiyon yazdık. Eğer yukarıdan
aşağıya doğru sayan bir sayaç yapmak isterseniz yukarıdaki fonksiyonu şu şekle
getirebilirsiniz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sayaç</span><span class="p">(</span><span class="n">sayı</span><span class="p">,</span> <span class="n">sınır</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sayı</span><span class="p">)</span>
<span class="k">if</span> <span class="n">sayı</span> <span class="o">==</span> <span class="n">sınır</span><span class="p">:</span>
<span class="k">return</span> <span class="s1">'bitti!'</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">sayaç</span><span class="p">(</span><span class="n">sayı</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">sınır</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sayaç</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
</pre></div>
</div>
<p>Burada, önceki fonksiyonda <cite>+</cite> olan işleci <cite>-</cite> işlecine çevirdik:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">return</span> <span class="n">sayaç</span><span class="p">(</span><span class="n">sayı</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">sınır</span><span class="p">)</span>
</pre></div>
</div>
<p>Fonksiyonumuzu çağırırken de elbette <cite>sayı</cite> parametresinin değerini <cite>100</cite>
olarak, <cite>sınır</cite> parametresinin değerini ise <cite>0</cite> olarak belirledik.</p>
<p>Bu arada, daha önce de bahsettiğimiz gibi, özyinelemeli fonksiyonlar,
özyinelemeye başlarken döndürdükleri değeri, özyineleme işleminin sonunda tek
tek geri döndürür. Bu özelliği göz önünde bulundurarak yukarıdaki fonksiyonu şu
şekilde de yazabilirdiniz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sayaç</span><span class="p">(</span><span class="n">sayı</span><span class="p">,</span> <span class="n">sınır</span><span class="p">):</span>
<span class="k">if</span> <span class="n">sayı</span> <span class="o">==</span> <span class="n">sınır</span><span class="p">:</span>
<span class="k">return</span> <span class="s1">'bitti!'</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">sayaç</span><span class="p">(</span><span class="n">sayı</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">sınır</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sayı</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sayaç</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">))</span>
</pre></div>
</div>
<p>Dikkat ederseniz burada <code class="docutils literal notranslate"><span class="pre">print(sayı)</span></code> satırını özyineleme işlevinin çıkışına
yerleştirdik. Böylece <cite>0</cite>’dan <cite>10</cite>’a kadar olan sayıları tersten elde ettik.
Ancak tabii ki yukarıdaki anlamlı bir kod yazım tarzı değil. Çünkü
fonksiyonumuzun yazım tarzıyla yaptığı iş birbiriyle çok ilgisiz. Sayıları
yukarı doğru saymak üzere tasarlandığı belli olan bu kodlar, yalnızca bir
<code class="docutils literal notranslate"><span class="pre">print()</span></code> fonksiyonunun özyineleme çıkışına yerleştirilmesi sayesinde yaptığı
işi yapıyor…</p>
<p>Yukarıda verdiğimiz örnekler sayesinde artık özyinelemeli fonksiyonlar hakkında
en azından fikir sahibi olduğumuzu söyleyebiliriz. Gelin isterseniz şimdi
özyinelemeli fonksiyonlarla ilgili (biraz daha mantıklı) bir örnek vererek bu
çetrefilli konuyu zihnimizde netleştirmeye çalışalım.</p>
<p>Bu defaki örneğimizde iç içe geçmiş listeleri tek katmanlı bir liste haline
getireceğiz. Yani elimizde şöyle bir liste olduğunu varsayarsak:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">l</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">],</span> <span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">11</span><span class="p">],</span> <span class="mi">12</span><span class="p">],</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">14</span><span class="p">]</span>
</pre></div>
</div>
<p>Yazacağımız kodlar bu listeyi şu hale getirecek:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">14</span><span class="p">]</span>
</pre></div>
</div>
<p>Bu amacı gerçekleştirebilmek için şöyle bir fonksiyon yazalım:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">liste</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
<span class="k">return</span> <span class="p">[</span><span class="n">liste</span><span class="p">]</span>
<span class="k">elif</span> <span class="ow">not</span> <span class="n">liste</span><span class="p">:</span>
<span class="k">return</span> <span class="p">[]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="n">l</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">],</span> <span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">11</span><span class="p">],</span> <span class="mi">12</span><span class="p">],</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">14</span><span class="p">]</span>
<span class="nb">print</span><span class="p">(</span><span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">l</span><span class="p">))</span>
</pre></div>
</div>
<p>Bu fonksiyonu yukarıdaki iç içe geçmiş listeye uyguladığınızda istediğiniz
sonucu aldığınızı göreceksiniz.</p>
<p>İlk bakışta yukarıdaki kodları anlamak biraz zor gelmiş olabilir. Ama endişe
etmenize gerek yok. Zira biz bu kodları olabildiğince ayrıntılı bir şekilde
açıklayacağız.</p>
<p>İlk olarak dip noktamızı tanımlıyoruz her zamanki gibi:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">liste</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
<span class="k">return</span> <span class="p">[</span><span class="n">liste</span><span class="p">]</span>
</pre></div>
</div>
<p>Fonksiyonumuzun temel çalışma prensibine göre liste içindeki bütün öğeleri tek
tek alıp başka bir liste içinde toplayacağız. Eğer liste elemanları üzerinde
ilerlerken karşımıza liste olmayan bir eleman çıkarsa bu elemanı <code class="docutils literal notranslate"><span class="pre">[liste]</span></code>
koduyla bir listeye dönüştüreceğiz.</p>
<p>Önceki örneklerden farklı olarak, bu kez kodlarımızda iki farklı dip noktası
kontrolü görüyoruz. İlkini yukarıda açıkladık. İkinci dip noktamız şu:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">elif</span> <span class="ow">not</span> <span class="n">liste</span><span class="p">:</span>
<span class="k">return</span> <span class="p">[]</span>
</pre></div>
</div>
<p>Burada yaptığımız şey şu: Eğer özyineleme esnasında boş bir liste ile
karşılaşırsak, tekrar boş bir liste döndürüyoruz. Peki ama neden?</p>
<p>Bildiğiniz gibi boş bir listenin 0. elemanı olmaz. Yani boş bir liste üzerinde
şu işlemi yapamayız:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
<span class="gp">>>> </span><span class="n">a</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n"><module></span>
<span class="gr">IndexError</span>: <span class="n">list index out of range</span>
</pre></div>
</div>
<p>Gördüğünüz gibi, boş bir liste üzerinde indeksleme işlemi yapmaya
kalkıştığımızda hata alıyoruz. Şimdi durumu daha iyi anlayabilmek için
isterseniz yukarıdaki kodları bir de ikinci dip noktası kontrolü olmadan yazmayı
deneyelim:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">liste</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
<span class="k">return</span> <span class="p">[</span><span class="n">liste</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="n">l</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">],</span> <span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">11</span><span class="p">],</span> <span class="mi">12</span><span class="p">],</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">14</span><span class="p">]</span>
<span class="nb">print</span><span class="p">(</span><span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">l</span><span class="p">))</span>
</pre></div>
</div>
<p>Bu kodları çalıştırdığımızda şu hata mesajıyla karşılaşıyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="n">File</span> <span class="s2">"deneme.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">9</span><span class="p">,</span> <span class="ow">in</span> <span class="o"><</span><span class="n">module</span><span class="o">></span>
<span class="nb">print</span><span class="p">(</span><span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">l</span><span class="p">))</span>
<span class="n">File</span> <span class="s2">"deneme.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">5</span><span class="p">,</span> <span class="ow">in</span> <span class="n">düz_liste_yap</span>
<span class="k">return</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="n">File</span> <span class="s2">"deneme.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">5</span><span class="p">,</span> <span class="ow">in</span> <span class="n">düz_liste_yap</span>
<span class="k">return</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="n">File</span> <span class="s2">"deneme.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">5</span><span class="p">,</span> <span class="ow">in</span> <span class="n">düz_liste_yap</span>
<span class="k">return</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="n">File</span> <span class="s2">"deneme.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">5</span><span class="p">,</span> <span class="ow">in</span> <span class="n">düz_liste_yap</span>
<span class="k">return</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="n">File</span> <span class="s2">"deneme.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">5</span><span class="p">,</span> <span class="ow">in</span> <span class="n">düz_liste_yap</span>
<span class="k">return</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="n">File</span> <span class="s2">"deneme.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">5</span><span class="p">,</span> <span class="ow">in</span> <span class="n">düz_liste_yap</span>
<span class="k">return</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="n">File</span> <span class="s2">"deneme.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">5</span><span class="p">,</span> <span class="ow">in</span> <span class="n">düz_liste_yap</span>
<span class="k">return</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="n">File</span> <span class="s2">"deneme.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">5</span><span class="p">,</span> <span class="ow">in</span> <span class="n">düz_liste_yap</span>
<span class="k">return</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="ne">IndexError</span><span class="p">:</span> <span class="nb">list</span> <span class="n">index</span> <span class="n">out</span> <span class="n">of</span> <span class="nb">range</span>
</pre></div>
</div>
<p>Gördüğünüz gibi, biraz önce boş bir liste üzerinde indeksleme yapmaya
çalıştığımızda aldığımız hatanın aynısı bu. Çünkü kodlarımızın <code class="docutils literal notranslate"><span class="pre">else</span></code> bloğuna
bakarsanız liste üzerinde indeksleme yaptığımızı görürsünüz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">return</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
</pre></div>
</div>
<p>Elbette boş bir liste <code class="docutils literal notranslate"><span class="pre">liste[0]</span></code> veya <code class="docutils literal notranslate"><span class="pre">liste[1:]</span></code> gibi sorgulamalara
<code class="docutils literal notranslate"><span class="pre">IndexError</span></code> tipinde bir hata mesajıyla cevap verecektir. İşte böyle bir
durumda hata almamak için şu kodları yazıyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">elif</span> <span class="ow">not</span> <span class="n">liste</span><span class="p">:</span>
<span class="k">return</span> <span class="p">[]</span>
</pre></div>
</div>
<p>Böylece özyineleme esnasında boş bir listeyle karşılaştığımızda bu listeyi şu
şekle dönüştürüyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="p">[[]]</span>
</pre></div>
</div>
<p>Böyle bir yapı üzerinde indeksleme yapılabilir:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">a</span> <span class="o">=</span> <span class="p">[[]]</span>
<span class="gp">>>> </span><span class="n">a</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="go">[]</span>
</pre></div>
</div>
<p>Dip noktaya ulaşılana kadar yapılacak işlemler ise şunlar:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">return</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="n">düz_liste_yap</span><span class="p">(</span><span class="n">liste</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
</pre></div>
</div>
<p>Yani listenin ilk öğesine, geri kalan öğeleri teker teker ekliyoruz.</p>
<p>Gelin bir örnek daha verelim:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">topla</span><span class="p">(</span><span class="n">sayilar</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sayilar</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">ilk</span><span class="p">,</span> <span class="n">son</span> <span class="o">=</span> <span class="n">sayilar</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">sayilar</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="k">return</span> <span class="n">ilk</span><span class="o">+</span><span class="n">topla</span><span class="p">(</span><span class="n">son</span><span class="p">)</span>
</pre></div>
</div>
<p>Bu fonksiyonun görevi, kendisine liste olarak verilen sayıları birbiriyle
toplamak. Biz bu işi başka yöntemlerle de yapabileceğimizi biliyoruz, ama bizim
burada amacımız özyinelemeli fonksiyonları anlamak. O yüzden sayıları birbiriyle
toplama işlemini bir de bu şekilde yapmaya çalışacağız.</p>
<p>Elimizde şöyle bir liste olduğunu varsayalım:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">liste</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">]</span>
</pre></div>
</div>
<p>Böyle bir durumda fonksiyonumuz <cite>55</cite> çıktısı verir.</p>
<p>Gelelim bu fonksiyonu açıklamaya…</p>
<p>Her zamanki gibi ilk olarak dip noktamızı tanımlıyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sayilar</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">0</span>
</pre></div>
</div>
<p>Buna göre <cite>sayilar</cite> adlı listenin uzunluğu 1’in altına düşünce <cite>0</cite> değerini
döndürüyoruz. Burada <cite>0</cite> değerini döndürmemizin nedeni, listede öğe kalmadığında
programımızın hata vermesini önlemek. Eğer <cite>0</cite> dışında başka bir sayı
döndürürsek bu sayı toplama işleminin sonucuna etki edecektir. Toplama işleminin
sonucunu etkilemeyecek tek sayı <cite>0</cite> olduğu için biz de bu sayıyı döndürüyoruz.</p>
<p>Taban noktaya varılıncaya kadar yapılacak işlemler ise şunlar:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">ilk</span><span class="p">,</span> <span class="n">son</span> <span class="o">=</span> <span class="n">sayilar</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">sayilar</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="k">return</span> <span class="n">ilk</span><span class="o">+</span><span class="n">topla</span><span class="p">(</span><span class="n">son</span><span class="p">)</span>
</pre></div>
</div>
<p>Burada amacımız, listenin ilk sayısı ile listenin geri kalan öğelerini tek tek
birbiriyle toplamak. Bunun için <cite>sayilar</cite> adlı listenin ilk öğesini, listenin
geri kalanından ayırıyoruz ve ilk öğeyi <cite>ilk</cite>; geri kalan öğeleri ise <cite>son</cite> adlı
bir değişkene gönderiyoruz:</p>