Tutorial Python untuk bukan pengatur cara/Tambahan tentang List

Daripada Wikibooks

Kita sudah melihat list dan bagaimana ia dapat diguna. Sekarang melihatkan anda sudah memiliki pengetahuan latar tambahan, saya akan memberikan perincian tentang list. Kita mula dengan melihat cara-cara mendapatkan unsur-unsur dalam senarai dan kemudian kita akan membincangkan cara menyalin unsur-unsur tersebut.

Ini contoh penggunaan index untuk mendapatkan sebuah unsur yang terdapat dalam list:

>>> beberapa_nombor = ['sifar', 'satu', 'dua', 'tiga', 'empat', 'lima']
>>> beberapa_nombor[0]
'sifar'
>>> beberapa_nombor[4]
'empat'
>>> beberapa_nombor[5]
'lima'

Seharusnya kesemua contoh-contoh di atas tidak asing bagi anda. Jika anda mahukan item pertama dalam senarai atau list anda hanya perlu melihat index 0. Item kedua ialah index 1 dan seterusnya sehingga ke akhir senarai. Namun, bagaimana pula jika anda mahukan item terakhir dalam senarai? Satu cara ialah dengan mengguna fungsi len() beberapa_nombor[len(beberapa_nombor) - 1]. Kaedah ini terlaksana kerana fungsi len() sentiasa memulangkan nilai index terakhir tambah satu. Item kedua dari akhir pula boleh didapatkan seperti berikut beberapa_nombor[len(beberapa_nombor) - 2]. Ada cara yang lebih mudah bagi melakukan ini. Dengan Python item terakhir sentiasa index -1. Item kedua dari akhir ialah index -2 dan seterusnya. Berikut beberapa contoh:

>>> beberapa_nombor[len(beberapa_nombor) - 1]
'lima'
>>> beberapa_nombor[len(beberapa_nombor) - 2]
'empat'
>>> beberapa_nombor[-1]
'lima'
>>> beberapa_nombor[-2]
'empat'
>>> beberapa_nombor[-6]
'sifar'

Justeru apa jua item dapat diindekskan dengan dua cara: dari hadapan, dan dari belakang.

Satu lagi cara berguna untuk mendapatkan sebahagian senarai ialah dengan menggunakan slice atau hirisan. Ini satu lagi contoh yang dapat memberikan anda idea kegunaan slice:

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

Penghirisan digunakan bagi memulangkan sebahagian list atau senarai. Operator penghiris ditulis dalam bentuk barang[indeks_pertama:indeks_terakhir]. Penghirisan memotong senarai sebelum indeks_pertama dan sebelum indeks_terakhir, dan memulangkan bahagian di antara kedua-duanya. Anda boleh gunakan kedua-dua jenis indeks:

>>> benda[-4:-2]
['Stokin', 42]
>>> benda[-4]
'Stokin'
>>> benda[-4:6]
['Stokin', 42]

Satu lagi helah yang boleh digunakan dengan penghirisan ialah menghiris tanpa tetapan indeks. Jika indeks pertama tidak ditetapkan, Python akan membuat tanggapan bahawa permulaan senarai telah dipilih. Jika indeks terakhir pula tidak ditetapkan, tanggapannya ialah semua baki senarai dipilih. Ini beberapa contoh:

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

Ini sebuah program (diilhamkan HTML) (salin dan tampal dalam definisi pantun jika anda mahu):

pantun = ["<B>", "Bertanak", "nasi", "si anak", "Cina", "</B>", 
          "Belah", "buluh", "di atas", "batu;",
        "<B>", "Tuan", "bijak", "saya", "bertanya", "</B>",
        "Apa", "benda", "telinganya", "satu", ]

def dapatkan_tebal(teks):
    true = 1
    false = 0
    ## dapatkan_tebal memberitahu sama ada kita 
    ## sedang membaca teks tebal
    ialah_tebal = false
    ## blok_mula ialah indeks permulaan teks yang 
    ## tebal ataupun tidak.
    blok_mula = 0
    for index in range(len(teks)):
        ## Kendali permulaan teks tebal
        if teks[index] == "<B>":
            if ialah_tebal:
                print "Ralat: Bold tambahan"
            ## cetak  "Tidak Tebal:", teks[blok_mula:index]
            ialah_tebal = true
            blok_mula = index + 1
        ## Kendali penghujung teks tebal
        ## Ingat bahawa bilangan terakhir dalam penghirisan ialah indeks
        ## selepas indeks terakhir yang digunakan.
        if teks[index] == "</B>":
            if not ialah_tebal:
                print "Ralat: Penutup Bold tambahan"
            print "Tebal [", blok_mula, ":", index, "]", teks[blok_mula:index]
            ialah_tebal = false
            blok_mula = index + 1

dapatkan_tebal(pantun)

dan outputnya:

Tebal [ 1 : 5 ] ['Bertanak', 'nasi', 'si anak', 'Cina']
Tebal [ 11 : 15 ] ['Tuan', 'bijak', 'saya', 'bertanya']

Fungsi dapatkan_tebal() mengambil senarai yang dipisahkan kepada perkataan dan token. Token yang dicarinya ialah <B> yang memulakan teks tebal dan </B> yang mengakhiri teks tebal. Fungsi dapatkan_tebal() menggelintar dan mencari token-token permulaan dan pengakhir.

Ciri berikut senarai ialah ciri bagi menalin sesebuah senarai. Jika anda mencuba sesuatu yang mudah seperti ini:

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

Keputusan ini mungkin memeranjatkan kerana pengubahsuaian pada b menghasilkan perubahan pada a sekali. Apa yang terjadi ialah kenyataan b = a membuat b sebagai rujukan bagi a.

Ini bermakna b boleh difikirkan sebagai satu lagi nama buat a. Justeru, apa jua perubahan yang dilakukan pada b juga mengubah a. Walau bagaimanapun, ada juga umpukan yang tidak membuat dua nama bagi satu senarai:

>>> 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]

Dalam kes ini b bukan rujukan kepada a kerana ungkapan a * 2 mewujudkan sebuah senarai baru. Kemudian kenyataan b = a * 2 memberi b sebuah rujukan kepada a * 2 dan tidak kepada a. Semua operasi umpukan mewujudkan rujukan. Apabila anda menggunakan senarai sebagai sebuah argumen kepada sebuah fungsi, anda juga mewujudkan sebuah rujukan. Dalam kebanyakan masa anda tidak perlu risau tentang hakikat yang anda mencipta rujukan dan bukan salinan. Namun, apabila anda perlu membuat perubahan pada satu senarai tanpa mengubah nama lain senarai tersebut, anda harus memastikan yang anda telah membuat sebuah salinan.

Terdapat beberapa cara untuk membuat salinan sebuah senarai. Yang paling mudah ialah penghirisan oleh sebab operasi ini sentiasa akan membuat senarai baharu mahupun bahagian yang diris itu hanya sebahagian daripada sebuah senarai:

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

Membuat hirisan [:] akan mencipta sebuah salinan baru sesebuah senarai. Walau bagaimanpun, ia hanya akan membuat salinan senarai luaran. Mana-mana subsenarai measih kekal menjadi rujukan kepada subsenarai dalam senarai asal. Jadi, jika sesebuah senarai itu mengandungi sebuah lagi senarai, senarai dalaman ini juga perlu disalin sekali. Anda boleh melakukan itu secara insani, akan tetapi Python mempunyai sebuah modul yang dapat melakukannya. Anda boleh menggunakan fungsi deepcopy daripada modul copy:

>>> 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]]

Perhatikan, pertama sekali, bahawa a ialah senarai yang mengandungi senarai. Kemudian perhatikan apabila b[0][1] = 10 dilaksanakan, kedua-dua a dan b diubah, akan tetapi c tidak berubah. Ini berlaku kerana tatasusunan dalaman masih kekal sebagai rujukan apabila operator hirisan digunakan. Walau bagaimanapun dengan deepcopy, c disalin sepenuhnya.

Jadi, perlukah saya risau tentang rujukan setiap kali saya menggunakan fungsi atau =? Berita baiknya ialah anda hanya perlu risaukan tentang rujukan apabila menggunakan kamus dan senarai. Nombor dan rentetan mencipta rujukan apabila diumpukkan akan tetapi setiap operasi terhadap nombor dan rentetan yang mengubah mereka akan mencipta salinan baru dan dengan itu anda akan tidak boleh menukarnya tanpa disangka-sangka. Anda perlu berfikir tentang rujukan jika mengubah sebuah senarai ataupun sebuah kamus.

Pada saat ini anda mungkin berfikir mengapa rujukan digunakan. Alasan asalnya ialah kelajuan. Membuat rujukan kepada senarai yang mengandungi seribu unsur lebih pantas daripada menyalin kesemua unsur. Alasan yang lagi satu ialah ia membolehkan anda untuk membuat fungsi yang dapat mengubah senarai ataupun kamus yang digunakan sebagai input. Hanya, anda perlu ingat tentang rujukan jika anda berhadapan dengan masalah aneh yang data diubah bila sepatutnya ia tidak berubah.