# List
* Elimizdeki verileri gruplamak bir yapı altında tutmak isteyebiliriz
* Mesela bir sınıftaki öÄrencilerin notlarını tutmak istiyorum. 5 farklı öÄrenci var, Åimdiye kadar öÄrendiklerimizle Åöyle yapabilirdim:
```python
ogrenci_1 = 78
ogrenci_2 = 80
ogrenci_3 = 43
ogrenci_4 = 65
ogrenci_5 = 90
```
* Bunların hepsi bir sınıftaki notları ifade ediyor. Bunları bir veri tipi olarak bir arada tutsak daha mantıklı olmaz mı?
* `list` veri tipi de tam burada devreye giriyor. **Birden çok veriyi gruplayıp bir arada tutmak** istediÄimizde kullanabileceÄimiz bir yapı
* `list`ler belirtirken köÅeli parantezle belirtiyoruz: `[element1, element2,...]`.
* `list`ler içsel yapı içerdikleri için `non-scalar` veri tipidir
* Elemanları arasına virgül koyarak farklı eleman belirtmeye baÅladıÄımı ifade ediyorum
```python
notlar = [78, 80, 43, 65, 90]
```
```python
# bunun aynısını Åu Åekilde de tutabilirdik:
notlar = [ogrenci_1, ogrenci_2, ogrenci_3, ogrenci_4, ogrenci_5]
```
* Bu oluÅturduÄumuz yapının ilk elemanı ilk öÄrencinin notu, ikinci elemanı ikinci öÄrencinin notunu belirtiyor (bu mantık böyle devam ediyor). Böylece öÄrencilerin notlarını farklı 5 deÄiÅkende tutmak yerine bir veri tipi altında düzenli tutabilmiÅ olduk
* Nasıl ki stringlerde elemanlarına indexleme yaparak [0] gibi deÄerlerle ulaÅabiliyorsak, listlerde de aynı
* `notlar` listesinin ilk elemanına ulaÅmak için:
```python
# ogrenci_1 in notu
notlar[0]
```
* `list`lerin içine istediÄimiz veri tipini koyabiliriz. listleri sadece verilerimi içine koyduÄumuz bir kutu olarak düÅünün, listlerin tek yaptıÄı Åey bunları bir arada tutmak. Elemanları istediÄim veri objesi olabilir. int, float, string, hatta listler bile!
```python
["a","b"]
```
```python
[True, False]
```
```python
[[1,2], [3,4,5]]
```
## Listler Farklı Veri Tiplerini İçerebilir
* Aynı list'in içine farklı tipte veri tipleri koyabiliriz
```python
l = [1, 2, "a", "b", True, 4.5, [1,2,3]]
```
```python
l
```
## Indexing ve Slicing
* String konusunda yaptıÄımız indexleme mantıÄı ve slicing mantıÄı tamamen listler için de geçerli
```python
notlar
```
```python
notlar[0]
```
```python
notlar[-1]
```
```python
notlar[10]
```
```python
notlar[-1]
```
```python
notlar[1:]
```
```python
notlar[1:3]
```
```python
notlar[:200]
```
```python
notlar[:3000]
```
## Listlerin Elemanları DeÄiÅtirilebilir
* Listler `mutable` veri tipleridir. Elemanlarını güncelleyebiliriz
```python
notlar
```
* Diyelim ki ikinci öÄrencinin notunu eksik okuduk. 5 puan yükseltmek istiyoruz:
```python
notlar[1] += 5 # notlar[1] = notlar[1] + 5
```
```python
notlar
```
* Birden çok elemanı da deÄiÅtirebiliriz
```python
l = [1, 2, 3, 4]
```
```python
l[0:3]
```
```python
l[0:3] = 30, 40, 60
```
```python
l
```
* EÅit sayıda vermemiz de gerekmez, l[0:3] olacak yere solda yazdıÄımız yazılır sadece
```python
l[0:3] = 30, 40
```
```python
l
```
```python
l = [1, 2, 3, 4]
```
```python
l[0:3] = 30
```
* Slicing in sonucuna tek bir deÄer yazacaksak bile direk tek olarak veremeyiz, `iterable` olması gerekir. Bunun ayrıntısını ileride göreceÄiz Åimdilik sol tarafı list olarak verebileceÄimizi bilmeniz yeterli
```python
l[0:3] = [30]
```
```python
l
```
## len()
* Bize list'te kaç eleman olduÄunu verir
```python
l
```
```python
len(l)
```
## Listin Sonuna Eleman Eklemek
### append()
* İçine yazılan elemanı listenin sonuna ekler
```python
l = [1,2,3]
```
```python
l.append(200)
```
```python
l
```
### extend()
* İçine yazılan birden çok elemanı listenin sonuna ekler
```python
l = [1,2,3]
```
```python
l.extend([100,200,300])
```
```python
l
```
## Spesifik Bir Indexe Eleman Eklemek
* Belki list'in sonuna deÄil, spesifik bir indexine eleman eklemek istiyoruz. Bunu inser() ile yapabiliriz
```python
l = [1, 2, 3, 4, 5]
```
```python
l[0] = 100
```
```python
l
```
```python
l = [1, 2, 3, 4, 5]
```
```python
l.insert(0, 100) # is not l[0] = 100
```
* eÄer l[0] = 100 yazmıŠolsaydık, liste 100,2,3,4,5 e dönerdi, ama ben 1->100 dönüÅümü yapmak istemiyorum, ilk indexe 100 ü eklemek istiyorum. l.insert(0,100) tam da istediÄimi yapıyor. 0. indexe 100 deÄerini yazıyor ve `1` deÄerini saÄa kaydırıyor, listeden silmemiÅ oluyor
```python
l
```
```python
l.insert(3,44)
```
```python
l
```
## remove()
* Belirli bir elemanı listeden silmemize yarar. EÄer yazılan eleman listede yoksa error verir
```python
l = [1,2,3,4]
```
```python
l.remove(40)
```
Bunu try-except ile çözebiliriz ama daha o konuyu görmedik. Yine de aÅaÄıya kodu ekliyorum
```python
try:
l.remove(40)
except ValueError:
pass
```
* remove() sadece ilk gördüÄü deÄeri siler. l.remove(40) dersem ve listte 1 den çok 40 varsa ilk gördüÄünü siler
```python
l = [1,2,3,40,30,40]
```
```python
l.remove(40)
```
```python
l
```
## pop()
* listenin belirli indexindeki elemanı silmeye ve o deÄeri döndürmeye yarar
* remove() sadece siliyordu, pop() aynı zamanda o deÄeri döndürüyor
```python
l = [1,2,3,4,5,6]
```
```python
# It deletes and return the value, remove() just removes it
l.pop(1)
```
```python
l
```
```python
l = [1,2,3,4,5,6]
```
```python
l.pop(1) + 4
```
```python
l
```
```python
# out of range error
l.pop(100)
```
## count()
* count() un içine yazdıÄımız deÄerin listede kaç defa göründüÄünü döndürür
```python
l = [1, 2, 44, 4, 5, 1]
```
```python
l.count(1)
```
```python
l.count(44)
```
```python
l.count(1000)
```
## Aliasing
* Evet. Geldik olayların ilginç bir hal aldıÄı yere.
* Listeler bilgisayarın hafızasında integer, float gibi veri tiplerinin tutulduÄundan biraz daha farklı tutuluyor.
* a = 2 dediÄimiz zaman hafızada `a` adında bir kutucuk oluÅturuluyor demiÅtik
```python
a = 2
```

* `a` direkt o kutunun adı oluyor.
* Ama listelerde durum böyle deÄil. l = [1,2,3] gibi bir liste yarattıÄımızda, `l` kutunun adı deÄil, kutuyu iÅaret eden etiketin adı oluyor
```python
l = [1,2,3]
```

* Bu farkın getirdiÄi bazı yan etkiler var
* Mesela kutunun adı direkt deÄiÅken adı olduÄunda ve aÅaÄıdaki iÅlemi yaptıÄımızda:
```python
a = 2
b = a
```
```python
b
```
```python
a = a + 1
```
```python
a
```
```python
b
```
* `a` yı güncellesek de `b` güncellenmiyor. `b` sadece `a` kutusunun deÄerine eÅit olmuÅ oldu, kutunun kendisine deÄil
* Aynısını listlerde yaptıÄımızda:
```python
l = [1,2,3]
```
```python
l2 = l
```
```python
l
```
```python
l2
```
```python
l[0] = 200
```
```python
l
```
```python
l2
```
* **l2 de güncellendi!**
* Ãünkü `l2 = l` dediÄimizde l2, l etiketinin deÄerine eÅit oldu, iki etikette aynı kutuyu, veri objesini gösteriyor, o yüzden listeyi güncellemem ikisine de yansıyor.

* Git aynı deÄerle baÅka bir kutucuk yarat ve oraya etiket ol diyerek güncellenmemesini saÄlayabilirim
* Bunu copy() ile yapacaÄız

```python
l2 = l.copy()
```
```python
l
```
```python
l2
```
```python
l[0] = 300
```
```python
l
```
```python
l2
```
## Listlerde Concatenation
* `+` operatörü listlerde concatenation yapar
```python
l = [1,2,3]
```
```python
l2 = [4,5,6]
```
```python
l
```
```python
l2
```
```python
l + l2
```
```python
l
```
```python
l2
```
```python
l3 = l + l2
```
```python
l3
```
## Belirli Bir Elemanın Indexini Bulmak
```python
l = [1, 2, 3, 4, 3, 5, 6]
```
```python
l
```
```python
# İlk hangi indexte görünüyorsa onun deÄerini döndürür
l.index(3)
```
```python
l.index(4)
```
```python
# listede olmayan deÄerler için error verir
l.index(100)
```
## List'i Tersine Ãevirmek
```python
l = [1,2,3,4]
```
```python
l.reverse() # inplace: yani l'yi günceller
```
```python
l
```
```python
l = [1,2,3,4]
```
* Aynısını slicing mantıÄı ile de yapabilirdik
```python
l[::-1]
```
```python
l
```
```python
l3 = l[::-1]
```
```python
l3
```
```python
l
```
* Orijinalini güncellemiyor, variable assignment yapmamız lazım güncellemesi için
```python
l = l[::-1]
```
```python
l
```
## List'in Elemanlarını Sıralamak (sorting)
* sorted() orijinal listeyi güncellemez
* sorted() ve .sort() a bakacaÄız. İkisi de default olarak küçükten büyüÄe sıralar. Sayısal verilerde sayısal deÄerine göre, stringlerde alfabetik sıraya göre sıralar
```python
l = ["b","a","c"]
```
```python
sorted(l)
```
['a', 'b', 'c']
```python
l
```
['b', 'a', 'c']
```python
l3 = sorted(l)
```
```python
l3
```
['a', 'b', 'c']
* .sort() günceller
```python
l = ["b","a","c"]
```
```python
l.sort() # inplace
```
```python
l
```
['a', 'b', 'c']
```python
l = [1,2,10,3,-1]
```
```python
sorted(l)
```
[-1, 1, 2, 3, 10]
```python
l
```
[1, 2, 10, 3, -1]
```python
# küçükten büyüÄe sıralar
l.sort()
```
```python
l
```
[-1, 1, 2, 3, 10]
```python
l = ["b","a","c","1","3","4"]
```
```python
l.sort()
```
```python
l
```
['1', '3', '4', 'a', 'b', 'c']
```python
l = [1,3.1,2,0.6]
```
```python
l.sort()
```
```python
l
```
[0.6, 1, 2, 3.1]
```python
l = ["b","a","c",1,2]
```
```python
l.sort()
```
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)