Python101 – Listelere devam

Listeleri ve nasıl kullanılabileceklerini gördük. Şimdi biraz daha bildiğimize göre listeler hakkında daha fazla ayrıntıya girelim. İlk önce bir listedeki öğelere ulaşmanın daha fazla yoluna bakacağız ve daha sonra bunları kopyalama hakkında konuşacağız.

Aşağıda, listenin tek bir öğesine erişmek için index kullanmanın bazı örnekleri bulunuyor:

>>> some_numbers = ['zero', 'one', 'two', 'three', 'four', 'five']
>>> some_numbers[0]
'zero'
>>> some_numbers[4]
'four'
>>> some_numbers[5]
'five'

Tüm bu örnekler size tanıdık gelmeli. Listedeki ilk öğeyi istiyorsanız, dizin 0’a bakmanız yeterli. İkinci öğe dizin 1 vb. Ancak listedeki son öğeyi istiyorsanız ne yapacaksınız? len() gibi bir işlev kullanabiliriz; some_numbers[len(some_numbers) - 1]. Bu işlev her zaman son dizinden bir fazlasını döndürdüğü için -1 yazıyoruz. Sondan bir önceki için ise some_numbers[len(some_numbers) - 2].

Bunu yapmanın daha kolay bir yolu ise -1 indexini kullalnmak. Python’da son öğe her zaman dizin -1’dir. Sondan bir önceki -2 vb.

>>> some_numbers[len(some_numbers) - 1]
'five'
>>> some_numbers[len(some_numbers) - 2]
'four'
>>> some_numbers[-1]
'five'
>>> some_numbers[-2]
'four'
>>> some_numbers[-6]
'zero'

Dolayısıyla listedeki herhangi bir öğe iki şekilde dizine eklenebilir: önden ve arkadan.

Listelerin bir kısmını almanın bir başka yararlı yolu da dilimleme kullanmaktır. Ne için kullanılabileceği hakkında size bir fikir vermek için başka bir örneğe bakalım:

>>> things = [0, 'Fred', 2, 'S.P.A.M.', 'Stocking', 42, "Jack", "Jill"]
>>> things[0]
0
>>> things[7]
'Jill'
>>> things[0:8]
[0, 'Fred', 2, 'S.P.A.M.', 'Stocking', 42, 'Jack', 'Jill']
>>> things[2:4]
[2, 'S.P.A.M.']
>>> things[4:7]
['Stocking', 42, 'Jack']
>>> things[1:5]
['Fred', 2, 'S.P.A.M.', 'Stocking']

Dilimleme, listenin bir bölümünü döndürmek için kullanılır. Dilimleme işleci liste[ilk_index:son_index] formundadır. Dilimleme, listeyi ilk_index öncesinde ve son_index öncesinde keser ve aradaki parçaları döndürür. Her iki dizin oluşturma türünü de kullanabilirsiniz: 

>>> things[-4:-2]
['Stocking', 42]
>>> things[-4]
'Stocking'
>>> things[-4:6]
['Stocking', 42]

Dilimleme ile ilgili başka bir hile de belirtilmemiş dizindir. İlk index belirtilmezse, listenin başlangıcı varsayılır. Son index belirtilmezse, listenin geri kalanı varsayılır:

>>> things[:2]
[0, 'Fred']
>>> things[-2:]
['Jack', 'Jill']
>>> things[:3]
[0, 'Fred', 2]
>>> things[:-5]
[0, 'Fred', 2]

Başka bir örneğe bakalım:

poem = ["<B>", "Jack", "and", "Jill", "</B>", "went", "up", "the",
        "hill", "to", "<B>", "fetch", "a", "pail", "of", "</B>",
        "water.", "Jack", "fell", "<B>", "down", "and", "broke",
        "</B>", "his", "crown", "and", "<B>", "Jill", "came",
        "</B>", "tumbling", "after"]

def get_bold(text):
    true = 1
    false = 0
    ## is_bold tells whether or not we are currently looking at 
    ## a bold section of text.
    is_bold = false
    ## start_block is the index of the start of either an unbolded 
    ## segment of text or a bolded segment.
    start_block = 0
    for index in range(len(text)):
        ## Handle a starting of bold text
        if text[index] == "<B>":
            if is_bold:
                print("Error: Extra Bold")
            ## print "Not Bold:", text[start_block:index]
            is_bold = true
            start_block = index + 1
        ## Handle end of bold text
        ## Remember that the last number in a slice is the index 
        ## after the last index used.
        if text[index] == "</B>":
            if not is_bold:
                print("Error: Extra Close Bold")
            print("Bold [", start_block, ":", index, "]", text[start_block:index])
            is_bold = false
            start_block = index + 1

get_bold(poem)

çıktısı:

Bold [ 1 : 4 ] ['Jack', 'and', 'Jill']
Bold [ 11 : 15 ] ['fetch', 'a', 'pail', 'of']
Bold [ 20 : 23 ] ['down', 'and', 'broke']
Bold [ 28 : 30 ] ['Jill', 'came']

get_bold() işlevi, sözcüklere ve belirteçlere ayrılmış bir liste alır. Aradığı belirteçler kalın metni başlatan <B> ve kalın metni bitiren </B> belirteçlerdir.

Listelerle yapabileceğimiz bir başka şey ise bunları kopyalamaktır. Aşağıdaki gibi basit bir örneğe bakalım:

>>> a = [1, 2, 3]
>>> b = a
>>> print(b)
[1, 2, 3]
>>> b[1] = 10
>>> print(b)
[1, 10, 3]
>>> print(a)
[1, 10, 3]

Çıktıt muhtemelen şaşırtıcı görünüyor, çünkü sadece b üzerinde bir değişiklik yapıldı ama sonuç ikisinde de aynı oldu. Olan şu ki, b=a ifadesi ile b, a’ya bir gönderme yapıyor. Bu, b’nin a için başka bir isim olarak düşünülebileceği anlamına gelir. Bu nedenle b’deki değişikliklerde de a değişiyor. Ancak bazı atamalar bir liste için iki ad oluşturmaz: 

>>> a = [1, 2, 3]
>>> b = a * 2
>>> print(a)
[1, 2, 3]
>>> print(b)
[1, 2, 3, 1, 2, 3]
>>> a[1] = 10
>>> print(a)
[1, 10, 3]
>>> print(b)
[1, 2, 3, 1, 2, 3]

Bu durumda, b=a*2 ifadesi yeni bir liste oluşturduğundan b, a’ya gönderme/referans değildir. Dolayısıyla bu ifade yeni bir liste oluşturur. Aslında, tüm atama işlemleri bir referans oluşturur. Bir listeyi bir işleve bağımsız değişken olarak iletdiğinizde de bir referans oluşturursunuz. Çoğu zaman kopya yerine referans oluşturma konusunda endişelenmenize gerek kalmaz. Ancak, bir listeye değişiklik yapıp diğerine yapmak istemediğinizde bir kopya oluşturduğunuzdan emin olmanız gerekir. 

Listenin bir kopyasını yapmanın birkaç yolu bulunur. Çoğu zaman çalışan en basit yöntem dilim işlecidir, çünkü tüm listenin bir dilimi olsa bile her zaman yeni bir liste oluşturur:

>>> a = [1, 2, 3]
>>> b = a[:]
>>> b[1] = 10
>>> print(a)
[1, 2, 3]
>>> print(b)
[1, 10, 3]

Dilimi almak listenin yeni bir kopyasını oluşturur. Ancak yalnızca dış listeyi kopyalar. Liste içindeki herhangi bir alt liste hala özgün listedeki alt listeye referanstır. Bu nedenle, liste, listeler içerdiğinde, iç listelerin de kopyalanmış olmasına özen göstermeniz gerekir. Bunu manuel olarak yapabilirsiniz, ancak Python zaten bunu yapmak için bir modül içerir. copy modülünün işlevlerini kullanırsınız: 

>>> import copy
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = a[:]
>>> c = copy.deepcopy(a)
>>> b[0][1] = 10
>>> c[1][1] = 12
>>> print(a)
[[1, 10, 3], [4, 5, 6]]
>>> print(b)
[[1, 10, 3], [4, 5, 6]]
>>> print(c)
[[1, 2, 3], [4, 12, 6]]

Öncelikle a’nın bir liste listesi olduğuna dikkat edin. Ardından, b[0][1] = 10 komutunun a ve b listelerinin her ikisi için de çalıştığına, ancak c için çalışmadığına olmadığına dikkat edin. Bunun nedeni, dilim işleci kullanıldığında iç dizilerin hala referans olmasıdır. Ancak c, deepcopy ile tamamen

Peki, her zaman referanslar hakkında endişelenmeli miyim? İyi haber, yalnızca sözlükleri ve listeleri kullanırken referanslar hakkında endişelenmeniz gerekir. Sayılar ve dizeler atandığında referanslar oluşturur, ancak bunları değiştiren sayılar ve dizeler üzerindeki her işlem yeni bir kopya oluşturur, böylece bunları hiçbir zaman beklenmedik şekilde değiştiremezsiniz. Bir listeyi veya sözlüğü değiştirirken referansları düşünmeniz gerekir. 

Şimdiye kadar muhtemelen referansların neden kullanıldığını merak ediyorsunuzdur? Temel sebep hızdır. Bin öğeli bir listeye referans yapmak, tüm öğeleri kopyalamaktan çok daha hızlıdır. Diğer neden, girilen listeyi veya sözlüğü değiştirmek için bir işleve sahip olmanızı sağlar. Verilerin değiştirilmemesi gerekirken değiştirilmesiyle ilgili garip bir sorununuz varsa referansları hatırlamanız yeterlidir.

Liste üreteçleri ile ilgili daha detaylı bir okuma yapmak isterseniz buradan devam edebilirsiniz.

Bir yorum yapın

E-posta hesabınız yayımlanmayacak.

To top