Python dökümanlarına göre yerleşik veri türleri nümerik, dizi, mapping, class, nesne ve hatalar olarak tanımlanır. Önce bu veri türlerinin neleri içerdiklerine bakalım:
Nümerik Türler: int
, float
, complex
Dizi: list
, tuple
, range
Yazı dizisi: str
Binary Diziler: bytes
, bytearray
, memoryview
Set türleri: set
, frozenset
Mapping türleri: — dict
Ve diğerleri:
Modüller, sınıflar, fonksiyonlar, metotlar ve diğerleri.
Bu kadar veri türü olması biraz kafa karıştırıcı ve karmaşık gelse de, Python’un dil yapısı bize şu kolaylığı sağlıyor; Python değişkeninizi tanımladığınızda ne tür bir veri ile ilgilendiğinizi bilecek kadar zeki. Bu yüzden değişken tanımlarken veri türü belirtmemize gerek kalmıyor. Örneğin
ogrenci = 'Selam!'
print (ogrenci)
#Çıktı Selam!
ogrenci = 7
print (ogrenci)
#Çıktı 7
ogrenci = [1, 2, 3]
print (ogrenci)
#Çıktı [1,2,3]
Yukarıdaki tanımda öğrenci değişkeni sırasıyla bir string’e, int’e veya list’e işaret ediyor. Bununla birlikte, veri türlerine ait detayları bilmemiz de bu veri türlerinde hangi operatörleri kullanabileceğimizi analmak adına önemli.
bool veri türü
bool: True veya False’ın boole değeri. Boole‘larda ve, veya, değil, gibi mantıksal işlemler gerçekleştirilebilir.
x or y # x False ise y, değilse x
x and y # x False ise x, değilse y
not x # x True ise False, değilse True
Python 2.x ve Python 3.x’te boolean aynı zamanda int‘dir. Bool
türü, int
türünün bir alt sınıfıdır ve True
ve False
bu türün tek örnekleridir:
issubclass(bool, int) # True
isinstance(True, bool) # True
isinstance(False, bool) # True
Aritmetik işlemlerde boole değerleri kullanılıyorsa, bu değerler bir tamsayı ile tanımlanır: (True:1, False:0)
True + False == 1 # 1 + 0 == 1
True * True == 1 # 1 * 1 == 1
Bunu biraz daha açalım.
Aslında C ve benzeri dillerde gerçek bir Boolean türü veya değeri bulunmaz. Bunun yerine int kullanılır. 0 değeri false, diğer tüm değerler ise true verir.
Python bunu tüm değerlere geneller. Her ne kadar bir Boolean türü olsa da, bu, yukarıda dediğimiz gibi int classının bir alt sınıfıdır. True
ve False
değerleri de tam anlamıyla sırasıyla 1
ve 0
değerlerine karşılık gelir. Herhangi bir değer bool() çağırıldığında Boolean türüne dönüştürülür:
>>> bool(5)
True
>>> bool(0)
False
>>> bool("foo"), bool([1,2,3])
True, True
>>> bool(""), bool([])
False, False
Bir değerin “gerçekliği” o değerin türüne göre değişir. Genel bir ifade ile söylemek gerekirse, sıfır ve boş yapılar False’a, diğer yapılar ise True’ya işaret eder. Dahası, and
veya or
ifadelerinin bir Boolean değeri döndürmesine gerek yoktur:
x and y == y if bool(x) else x
x or y == x if bool(x) else y
bool
x değerinin true olup olmadığını kontrol eder, ancak sonuç x veya y’nin kendi değerlerine eşit olur.
and
kullanarak aşağıdaki ifadeyi çözümleyelim:
a = 5
b = -1
c = 2
print((c) and (b<0) and (a>0))
c and b<0 and a>0 == (b < 0 if bool(c) else c) and a > 0
== b < 0 if bool(2) else c) and a > 0
== (b < 0 if True else c) and a > 0
== b < 0 and a > 0
== a > 0 if bool(b < 0) else b < 0
== a > 0 if bool(-1 < 0) else b < 0
== a > 0 if bool(True) else b < 0
== a > 0 if True else b < 0
== a > 0
== 5 > 0
== True
Çözümleme yaparken a
, b
, ve c
değerlerini sona kadar yerlerine koymadık. Çünkü and
, or
, ve koşul ifadeleri tembeldir; Mutlaka gerekli olana kadar gerçek değeri kullanmazlar. Buna biraz sonra tekrar bakacağız.
Eğer c = 0
olarak tanımlarsak, sonuç olarak c
‘nin değerini alırız, c’nin Boolean değerini değil! Burada a
‘nın değerine de bakmamız gerekir, çünkü a > 0
aslında değerlendirilmez.
c and b<0 and a>0 == (b < 0 if bool(c) else c) and a > 0
== (b < 0 if bool(0) else c) and a > 0
== (b < 0 if False else c) and a > 0
== c and a > 0
== a > 0 if bool(c) else c
== a > 0 if bool(0) else c
== a > 0 if False else c
== c
== 0
Bool örnekleri
Aşağıdaki liste öğelerine bakalım. Python boş öğe, 0 ve False harici tüm değerleri True olarak görecektir.
['true', '1', 't', 'y', 'yes', 'yeah', 'yup', 'certainly', 'uh-huh', 0]
Dolayısıyla yukarıda sadece bir öğe için (son öğe, 0) False değeri elde ederken, diğer öğeler True döner.
Aşağıdaki kullanımları inceleyelim:
>>> bool(1)
True
>>> bool(0)
False
>>> int(bool(1))
1
>>> int(bool(0))
0
1 değerinin bool sorgusu True döndürür. 0 değeri ise beklediğimiz gibi False. Bu ifadelerden çıkan sonuçları int’e dönüştürmek isteseydik yine 1 ve 0’ı elde ederdik.
değil işlemine bakalım:
>>> not not 1
True
>>> not not 0
False
>>>
ilk ifadeyi not (not 1)
olarak düşünürsek, parantez içerisindeki ifade 0 olur, önündeki not ifadesi de bunu tekrar 1’e yani bool True değerinen dönüştürür. Bu ifadeleri int’e dönüştürerek sonucu daha rahat görebiliriz.
>>> int(not not 1)
1
>>> int(not not 0)
0
>>>
Sayılar
Python’da birden farklı türde sayısal değeri ifade edebiliriz. Genel itibariyle tamsayılar int türünde, ondalıklı sayılar ise kayan nokta sayıları (floating point) türünde işlenir. Tam sayılar da bazı programlama dillerinde alt kategorilere ayrılabilir. Örneğin negatif ve pozitif sayılar, long türünde (büyük değere) sahip sayılar farklı türlerde tanımlanır.
Tam sayılar
Öncelikle tam sayılara bakalım. Python otomatik olarak hangi nümerik veri türünü kullandığınızı anlar. Python 2 ile çalışıyorsanız int/long ayrımını yapabilmek için değerin boyutuna bakar.
Maksimum int değeri (Python 2’de) 65535’tir. Bu değerden daha büyük olan değerler long türünde olacaktır.
Örneğin:
>> print type(65535)
<type 'int'>
>>> print type(65536*65536)
<type 'long'>
Gelelim Python 3’e. Python 3’te long veri türü kaldırıldı ve tüm tam değer ifadeler int sınıfı ile halledilecek şekilde tasarlandı. Buna göre, int’in boyutu CPU mimarinize bağımlı olacaktır.
Örneğin:
- 32 bit sistemde tamsayı için varsayılan tür ‘Int32’
- 64 bit sistemde tamsayı için varsayılan tür ‘Int64”tür
Her türdeki min/max değerlerine bakalım:
- Int8: [-128,127]
- Int16: [-32768,32767]
- Int32: [-2147483648,2147483647]
- Int64: [-9223372036854775808,9223372036854775807]
- Int128: [-170141183460469231731687303715884105728,170141183460469231731687303715884105727]
- UInt8: [0,255]
- UInt16: [0,65535]
- UInt32: [0,4294967295]
- UInt64: [0,18446744073709551615]
- UInt128: [0,340282366920938463463374607431768211455]
Eğer tamsayınızın boyutu yukarıda verilen bir rdeğeri geçerse, Python otomatik olarak veri türürnü dedğiştirecek ve buna uygun memory ayarlayacaktır. Python 2’de ‘long”a dönüştürülen sayı, Python 3’tee sadece bir sonraki boyutta olan int’e dönüştürülür.
Örneğin: 32 bit sistem kullanaıyorsanız, int için varsayılan maksimum değeriniz 2147483647 olacaktır. Eğer 2147483648 sayısını değer olarak verirseniz (veya daha fazlasını), veri türü Int64’e dönüştürülür.
Not: Python 3’te, yerleşik type() metodunu kullanmak her zaman <class 'int'>
sonucunu verir – hangi büyüklükte int kullandığınızdan bağımsız olarak.
Tekrar edelim: Python’un eski sürümlerinde long
türü bulunurdu ve bu tür int
‘ten farklıydı. Artık bu iki tür birleştirildi ve tüm tamsayılar int ile tanımlanır hale geldi.
a = 2
b = 100
c = 123456789
d = 38563846326424324
float (kayan nokta sayıları)
Ondalıklı bir sayı ile ilgileniyorsanız veri türümüz float olacaktır. Float değerleri için hassasiyet uygulamaya ve sistem mimarisine bağlıdır. Örneğin CPython için float
veri türü bir C double
türüne karşılık gelir.
a = 2.0
b = 100.e0
c = 123456789.e1
complex – Karmaşık sayılar
a = 2 + 1j
b = 100 + 10j
Karmaşık sayılarla işlem yapıldığında <, <=,> ve >= operatörlerinin TypeError
hatası oluşturacağını unutmayın.
Peki tüm integer ve float sayıları aynı data türünde mi değerlendirilir?
Öncelikle, yukarıda gördüğümüz gibi, aslında üç farklı türde nümerik yapı var; integer, float, ve complex sayılar. Floating sayılar C’de double kullanarak işlenmiştir.
Burada kafa karışıklığına sebep olan nokta matematik açısından herhangi bir int
veya float
türü aslında reel sayılar kümesindedir. Öte yandan, numbers
modülü nümerik abstract temel sınıfları tanımlar; Number
, Complex
, Real
, Rational
, ve Integral
. Ancak bu modülde tanımlanan hiç bir tür nesne olarak oluşturulmaz.
Bu sınıfları bir nümerik ifadenin hangi temel türe ait olduğunu görmek için kullanırız:
In[1]: import numbers
In [2]: isinstance(10, numbers.Integral)
Out[2]: True
In [3]: isinstance(10.5, numbers.Integral)
Out[3]: False
Karakter dizileri (string)
Python 3.x Sürümü ≥ 3.0
str: bir unicode dizisi.
bytes: bir bit dizisi.
Python 2.x Sürümü ≤ 2.7
str: bir bit dizisi.
bytes: str ile eşanlamlı.
unicode: bir unicode dizisi.
Diziler ve koleksiyonlar
Python, sıralı diziler ve sırasız koleksiyonlar (set
ve dict
gibi) arasında ayrım yapar.
- String türleri (
str
,bytes
,unicode
) dizidir. - reversed: Ters fonksiyonu ile ters çevrilmiş bir karakter dizisi
a = reversed('hello')
- tuple: Herhangi bir türde n öğeli sıralı koleksiyon (n> = 0).
a = (1, 2, 3)
b = ('a', 1, 'python', (1, 2))
b[2] = 'baska bir sey' # TypeError hatası
tuple indekslemeyi destekler; değişmez türdür; eğer tüm üyeleri hashable ise hashable‘dır.
list: n öğeden oluşan sıralı koleksiyon (n> = 0)
a = [1, 2, 3]
b = ['a', 1, 'python', (1, 2), [1, 2]]
b[2] = 'baska bir sey' # geçerli kullanım
list hashable değildir ve değişir türdür.
set: Sırasız benzersiz öğe koleksiyonudur. Öğeleri hashable olmalıdır.
a = {1, 2, 'a'}
dict: Benzersiz anahtar/değer çiftlerinden oluşan sıralanmamış koleksiyondur; anahtarları hashable olmalıdır.
a = {1: 'bir',
2: 'iki'}
b = {'a': [1, 2, 3],
'b': 'bir karakter dizisi'}
Bir nesne, hiç değişmeyen bir hash değerine sahipse (__hash__() metodu gerektirir) ve diğer nesnelerle karşılaştırılabiliyorsa (__eq__() metodu gerektirir) hashable‘dır. Eşitliği karşılaştırılan hashable nesneler aynı hash değerine sahip olmalıdırlar.
Yerleşik sabitler
Yerleşik veri türleriyle bağlantılı olarak, yerleşik ad alanında (namespace), az sayıda da olsa, yerleşik sabitler bulunur:
True: Yerleşik tür bool‘un true (doğru) değeri
False: Yerleşik bool türünün false (yanlış) değeri
Null: Bir değerin olmadığını bildirmek için kullanılan tekil nesne.
Ellipsis veya …: Python3+ çekirdeğinde her yerde kullanılabilen ve Python2.7+’de dizi gösteriminin bir parçası olarak sınırlı kullanımı olan tür.
numpy ve ilgili paketler bunu dizilerde ‘her şeyi içer’ anlamındaki tür olarak kullanır.
NotImplemented: Özel bir fonksiyonun kullanılan argümanları desteklemediğini belirtmek için kullanılan tekil bir nesne. Python bu durumda, varsa, alternatifleri dener.
a = None # Hiçbir değer atanmaz. Geçerli bir veri türü daha sonra atanabilir.
Python 3.x Versiyon ≥ 3.0:None
için herhangi bir sıralama bulunmaz. Sıralama karşılaştırma operatörlerinin (<, <=,> =,>) kullanılması ise (artık) desteklenmez ve dolayısıyla TypeError
oluşturur.
Python 2.x Version ≤ 2.7
None herhangi bir sayıdan her zaman küçüktür. (Örneğin, None < -32
ifadesinin değeri True
olarak değerlendirilir).
Python’da değişkenin türü nasıl öğrenilir?
Python’da, yerleşik type
fonksiyonunu kullanarak bir nesnenin türünü kontrol edebiliriz.
a = '123'
print(type(a))
# Çıktı: <class 'str'>
b = 123
print(type(b))
# Çıktı: <class 'int'>
Koşullu ifadelerde isinstance
metodu da kullanılabilir. Ancak, değişkenin türüne güvenmek genellikle tavsiye edilmez.
i = 7
if isinstance(i, int):
i += 1
elif isinstance(i, str):
i = int(i)
i += 1
type()
ve isinstance()
arasındaki farklar için Python’da type() ve isinstance() arasındaki farklar nelerdir yazısını okuyabilirsiniz.
Bir değişkenin NoneType
olup olmadığını test etmek için:
x = None
if x is None:
print('x'i zaten None tanımlamıştık, sürpriz olmadı.')
Veri türleri arası dönüşüm
Örneğin, ‘123’ str
tipindedir ve int
fonksiyonu kullanılarak tamsayıya dönüştürülebilir;
a = '123'
b = int(a)
‘123.456’ gibi bir float
karakter dizisinden dönüştürme float
fonksiyonu kullanılarak yapılabilir;
a = '123.456'
b = float(a)
c = int(a) # ValueError: invalid literal for int() with base 10: '123.456'
d = int(b) # 123
Dizi veya koleksiyon türleri de dönüştürülebilir;
a = 'hello'
list(a) # ['h', 'e', 'l', 'l', 'o']
set(a) # {'o', 'e', 'l', 'h'}
tuple(a) # ('h', 'e', 'l', 'l', 'o')
Explicit (belirli) string tanımlama
Tırnakların hemen önündeki tek harfli etiketlerle ne tür bir string tanımlamak istediğimizi belirtebiliriz.
- b’foo bar’: Python 3’te byte, Python 2’de str tanımlar
- u’foo bar’: Python 3’te str, Python 2’de unicode tanımlar
- ‘foo bar’: str tanımlar
- r’foo bar’: ham string adı verilen bir dize tanımlar. ham stringlerde özel kaçış karakterleri önemli değildir, yazılan her şey aynısı gibi algılanır.
normal = 'foo\nbar' # foo
# bar
kaciskarakteri = 'foo\\nbar' # foo\nbar
raw = r'foo\nbar' # foo\nbar
Python’da değişebilen ve değişmez veri türleri
Bir nesne sonradan değiştirilebilirse değişebilen olarak adlandırılır. Örneğin, bir listeyi bir fonksiyona aktardığımızda o liste değiştirilebilir:
def f(m):
m.append(3) # List'e bir sayı ekler, bu bir değişikliktir.
x = [1, 2]
f(x)
x == [1, 2] # Sonuç False olur, çünkü list'e bir öğe eklendi.
Herhangi bir şekilde değiştirilemeyen nesneler ise değişmez olarak adlandırılır. Örneğin, tamsayılar değişmezdir çünkü onları değiştirmenin bir yolu yoktur:
def bar():
x = (1, 2)
g(x)
x == (1, 2) # Hiçbir metod (1, 2) nesnesini değiştiremeyeceği için her zaman True olacaktır
Burada değişkenlerin kendilerinin değiştirilebilir olduğuna dikkat edin. Bu sayede x
değişkenini yeniden atayabiliriz, ancak bu, x
‘in daha önce işaret ettiği nesneyi değiştirmez. Sadece x
‘in yeni bir nesneye işaret etmesini sağlar.
Kopyaları değiştirilebilir olan veri türleri değişebilen veri türleri olarak adlandırılır.
Değişebilen nesne türleri;
- bytearray
- list
- set
- dict
Değişmez nesne türleri;
- int, long, float, complex
- str
- bytes
- tuple
- frozenset
- 1. Python’a Giriş
- 1.1. Değişkenler oluşturma ve değer atama
- 1.2. Girintiler (indentation)
- 1.3. Veri tipleri (Bu yazı)
- 1.4. Koleksiyon Türleri
- 1.5. Kullanıcı Girdisi
- 1.6. Dahili Modüller ve Fonksiyonlar
- 1.7. Python’da Modül Nasıl Oluşturulur
- 1.8. String Fonksiyonları – str ve repr
- 1.9. Pip kullanarak harici modüllerin kurulması
- 1.10. Help – Python’da Yardım Aracı