koddla

Yazılımcıları bilgi ile güçlendirir.

Python’da Veri Türleri

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: intfloatcomplex

Dizi: listtuplerange

Yazı dizisi: str

Binary Diziler: bytesbytearraymemoryview

Set türleri: setfrozenset

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 ab, ve c değerlerini sona kadar yerlerine koymadık. Çünkü andor, 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; NumberComplexRealRational, 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



Bir cevap yazın

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

Back to top