Питхон тупле против листе: сличности и разлике, објашњено

U ovom vodiču istražićemo sličnosti i razlike između Python tuple-ova i lista. Takođe ćemo objasniti kada je najbolje koristiti tuple.

Liste i tuple su ugrađene strukture podataka u Python-u. One se koriste za čuvanje kolekcije elemenata.

Od podrške za indeksiranje i sečenje do mogućnosti skladištenja heterogenih tipova podataka, može se činiti da tuple i liste imaju slične funkcije. Zato je važno razumeti sličnosti i razlike između njih, kako biste znali koju strukturu podataka treba koristiti.

Započnimo.

👩🏽‍💻 Možete pokrenuti Python REPL i pratiti ovaj vodič. Takođe, možete koristiti online Python editor za kodiranje.

Python Tuple naspram Liste: Koje su sličnosti?

Započnimo proučavanjem sličnosti između lista i tuple-ova. Za bolje razumevanje, koristićemo primere i za liste i za tuple-ove.

#1. Python Iterabilni objekti

U Python-u, liste se označavaju uglastim zagradama, dok se tuple-ovi označavaju običnim zagradama. Takođe, tuple-ove možete kreirati kao niz vrednosti razdvojenih zarezima – bez zagrada.

Obe strukture su iterabilne, što znači da možete proći kroz njih koristeći for petlju.

Sledeći blok koda prikazuje kako se iterira kroz listu.

    nums = [2,6,7,10]
    print(f"Tip od nums je {type(nums)}")
    for num in nums:
      print(num)

    # Output
    # Tip od nums je <class 'list'>
    # 2
    # 6
    # 7
    # 10
  

Kao što je prikazano, možete iterirati kroz tuple koristeći petlju.

    nums = (2,6,7,10)

    # Napomena: nums = 2,6,7,10 je takođe validan tuple. Ako treba, uradite brzu proveru!

    print(f"Tip od nums je {type(nums)}")
    for num in nums:
      print(num)

    # Output
    # Tip od nums je <class 'tuple'>
    # 2
    # 6
    # 7
    # 10
  

#2. Podrška za kreiranje iz drugih sekvenci

Sledeća sličnost između lista i tuple-ova je da se mogu kreirati iz postojećih sekvenci, kao što su stringovi.

    sample_str = "Coding!"
  

Sledeći blok koda prikazuje kako list(string) vraća listu, čiji su elementi karakteri u stringu.

    list_from_str = list(sample_str)
    print(list_from_str)

    # Output
    # ['C', 'o', 'd', 'i', 'n', 'g', '!']
  

Slično, tuple se može kreirati iz stringa ili druge sekvence koristeći tuple(sekvenca). Sledeći blok koda pokazuje kako to možete uraditi.

    tuple_from_str = tuple(sample_str)
    print(tuple_from_str)

    # Output
    # ('C', 'o', 'd', 'i', 'n', 'g', '!')
  

#3. Podrška za indeksiranje i sečenje

Python podržava nulto indeksiranje, gde je prvi element na indeksu nula, drugi na indeksu jedan, itd. Python takođe podržava negativno indeksiranje, gde je poslednji element na indeksu -1, pretposlednji na indeksu -2, itd.

    list_from_str = ['C', 'o', 'd', 'i', 'n', 'g', '!']
    print(list_from_str[1])
    # o
  

Element sa indeksom -2 je pretposlednji element, ‘g’.

    tuple_from_str = ('C', 'o', 'd', 'i', 'n', 'g', '!')
    print(tuple_from_str[-2])
    # g
  

Sečenje se koristi kada želite da radite sa delom liste ili tuple-a. lista[start:end] vraća deo liste počevši od start indeksa i ide do end – 1. Podrazumevana vrednost za start je 0, a za end je poslednji element iterabilnog objekta.

Možete seći tuple koristeći istu sintaksu. Hajde da napravimo delove liste i tuple-a koje smo ranije kreirali.

    list_from_str = ['C', 'o', 'd', 'i', 'n', 'g', '!']
    print(list_from_str[0:5])

    # ['C', 'o', 'd', 'i', 'n']
  

Pored start i end vrednosti, možete navesti i korak. tuple(start:end:step) vraća isečak tuple-a od start do end – 1, u koracima step.

    tuple_from_str = ('C', 'o', 'd', 'i', 'n', 'g', '!')
    print(tuple_from_str[::2])

    # ('C', 'd', 'n', '!')
  

Ovde postavljamo vrednost koraka na 2. Dakle, isečak sadrži svaki drugi element.

#4. Kolekcije više tipova podataka

U primerima koje smo dosad razmatrali, svi elementi u listi i tuple-u su bili istog tipa podataka.

Međutim, možete skladištiti vrednosti različitih tipova podataka unutar iste liste ili tuple-a.

Sledeći isječak koda, student_list, sadrži ime studenta kao string, godine kao integer i ocene kao float.

    student_list = ["John",22,96.5]
    for item in student_list:
      print(f"{item} je tipa {type(item)}")

    # Output
    # John je tipa <class 'str'>
    # 22 je tipa <class 'int'>
    # 96.5 je tipa <class 'float'>
  

Možemo smisliti sličan primer za tuple.

    student_tuple = ("Jane",23,99.5)
    for item in student_tuple:
      print(f"{item} je tipa {type(item)}")

    # Output
    # Jane je tipa <class 'str'>
    # 23 je tipa <class 'int'>
    # 99.5 je tipa <class 'float'>
  

#5. Podrška za testiranje članstva

I liste i tuple-ovi vam omogućavaju da testirate prisustvo određenih elemenata. Možete koristiti operator `in` da proverite da li se određeni element nalazi u listi ili tuple-u.

Izraz element in iterabilni objekat se procenjuje kao Tačno ako iterabilni objekat sadrži taj element; inače, Netačno.

    "Alex" in student_list
    # False

    "Jane" in student_tuple
    # True
  

Do sada ste naučili sličnosti između lista i tuple-ova u Python-u. Sada, hajde da proučimo ključne razlike između ove dve strukture podataka.

Python Tuple naspram Liste: Koje su razlike?

#1. Promenljivost lista i nepromenljivost tuple-ova u Python-u

Najvažnija razlika između liste i tuple-a u Python-u je to što je tuple nepromenljiv. To znači da ne možete menjati tuple na licu mesta.

▶ Evo primera.

    tuple1 = ("Java","Python","C++")
    tuple1[0] = "Rust"

    # Output
    # ----> 2 tuple1[0] = "Rust"

    # TypeError: 'tuple' object does not support item assignment
  

Lista je promenljiva struktura podataka, tako da možemo da modifikujemo listu promenom elementa na određenom indeksu, kao u sledećem bloku koda.

    list1 = ["Java","Python","C++"]
    list1[0] = "Rust"
    print(list1)

    # Output
    # ['Rust', 'Python', 'C++']
  

#2. Liste promenljive dužine naspram tuple-ova fiksne dužine

Python lista je struktura podataka promenljive dužine.

Možete uraditi sledeće:

  • Dodati element na kraj liste
  • Dodati elemente iz druge liste na kraj trenutne liste
  • Ukloniti elemente sa određenog indeksa iz liste
    list1 = [2,3,4,5]

    # dodaj element na kraj
    list1.append(9)
    print(list1)

    # dodaj elemente iz list2 na kraj list1
    list2 = [0,7]
    list1.extend(list2)
    print(list1)

    # ukloni element iz list1
    list1.pop(0)
    print(list1)
  

▶ Izlaz gornjeg isečka koda.

    # Output
    # [2, 3, 4, 5, 9]
    # [2, 3, 4, 5, 9, 0, 7]
    # [3, 4, 5, 9, 0, 7]
  

Tuple-ovi su strukture podataka fiksne dužine. Dakle, ne možete dodavati ili uklanjati elemente iz postojećeg tuple-a. Ali možete redefinisati tuple tako da sadrži različite elemente.

    tuple1 = (2,4,6,8)
    tuple1 = (1,8,9)
    print(tuple1)

    # Output
    # (1, 8, 9)
  

#3. Veličina u memoriji

Sada ćemo se nadovezati na ono što smo naučili u prethodnom odeljku: lista je struktura podataka promenljive dužine.

Kada prvo definišete listu, u memoriji joj se dodeljuje određena veličina. Sada, kada modifikujete listu koristeći metode append() ili extend(), trebalo bi da se dodeli dodatna memorija za skladištenje dodatih elemenata. Ova alokacija se skoro uvek vrši više od broja dodatih stavki.

Dakle, postoji potreba da se vodi evidencija o broju stavki u listi i dodeljenom prostoru. Pored toga, pošto su liste promenljive dužine, postoji pokazivač koji ukazuje na adresu elemenata liste. Kao rezultat, liste dužine k zauzimaju više memorije od tuple-a sa istim k elementima.

Evo jednostavne ilustracije.

Možete koristiti metodu getsizeof() ugrađenog sys modula na Python objektu da biste dobili veličinu objekta u memoriji.

    import sys

    list1 = [4,5,9,14]
    list_size = sys.getsizeof(list1)
    print(f"Veličina liste:{list_size}")

    tuple1 = (4,5,9,14)
    tuple_size = sys.getsizeof(tuple1)
    print(f"Veličina tuple-a:{tuple_size}")
  

Lista zauzima više memorije nego tuple za isti broj i vrednost elemenata, kao što je potvrđeno u izlazu ispod.

    # Output
    # Veličina liste:104
    # Veličina tuple-a:88
  

Kada treba da koristite Python tuple?

Iz razlika i sličnosti između Python lista i tuple-ova, znate da ako vam je potrebna promenljiva kolekcija, treba da koristite listu.

Ali kada treba da koristite tuple umesto toga?

O tome ćemo pričati u ovom odeljku.

#1. Kolekcija samo za čitanje

Kad god želite da kolekcija bude nepromenljiva, treba da je definišete kao tuple. Pretpostavimo da je boja = (243,55,103) tuple koji sadrži RGB vrednosti koje odgovaraju nijansi boje. Definisanje boje kao tuple-a osigurava da se ne može menjati.

U suštini, kada vam je potrebno da kolekcija bude samo za čitanje: vrednosti ne bi trebalo da se menjaju tokom programa, treba da razmislite o korišćenju tuple-a. Ovo će sprečiti nenamernu modifikaciju vrednosti.

#2. Ključevi rečnika

Na primer, kreirate rečnik koristeći elemente liste key_list kao ključeve. Možete koristiti metodu dict.fromkeys() da kreirate rečnik iz liste.

    key_list = list("ABCD")
    dict.fromkeys(key_list)

    # {'A': None, 'B': None, 'C': None, 'D': None}
  

Pretpostavimo da izmenite listu tako da sadrži ‘D’ kao prvi element (indeks 0) — pre nego što kreirate rečnik.

Sada, šta se dešava sa ključem rečnika ‘A’?

Ako pokušate da napravite rečnik iz liste ključeva i pristupite vrednosti koja odgovara ključu ‘A’, naići ćete na KeyError.

    key_list[0] = 'D'

    dict.fromkeys(key_list)['A']

    # ---------------------------------------------------------------------------
    # KeyError                                  Traceback (most recent call last)
    # <ipython-input-31-c90392acc2cf> in <module>()
    # ----> 1 dict.fromkeys(key_list)['A']

    # KeyError: 'A'
  

Ključevi rečnika treba da budu jedinstveni. Dakle, ne možete imati drugo ‘D’ kao ključ.

    dict.fromkeys(key_list)
    # {'B': None, 'C': None, 'D': None} # A više nije ključ.
  

Ako umesto toga koristite tuple, takva modifikacija je nemoguća i manje je verovatno da ćete naići na greške. Zbog toga bi trebalo da radije kreirate rečnik koristeći elemente iz tuple-a kao ključeve.

    key_tuple = tuple("ABCD")
    dict.fromkeys(key_tuple)
    # {'A': None, 'B': None, 'C': None, 'D': None}

    key_tuple[0] = 'D'
    # ---------------------------------------------------------------------------
    # TypeError                                 Traceback (most recent call last)
    # <ipython-input-12-2cecbefa7db2> in <module>()
    # ----> 1 key_tuple[0] = 'D'

    # TypeError: 'tuple' object does not support item assignment
  

#3. Argumenti funkcije

Nepromenljivost tuple-ova takođe ih čini pogodnim za prosleđivanje kao argumente funkcije.

Razmotrite sledeću funkciju find_volume() koja vraća zapreminu kvadra s obzirom na dimenzije: dužinu, širinu i visinu.

    def find_volume(dimensions):
      l,b,h = dimensions
      return l*b*h
  

Pretpostavimo da su ove dimenzije dostupne u listi pod nazivom dimensions. Poziv funkcije find_volume() sa dimensions kao argumentom vraća zapreminu.

    dimensions = [2,8,5]
    find_volume(dimensions)
    # 80
  

Uvek možete da promenite dimenzije sačuvane u listi.

    dimensions = [20,8,5]
    find_volume(dimensions)
    # 800
  

Međutim, ponekad ćete želeti da vrednosti ostanu konstantne i da se odupru promenama. Tada bi trebalo da razmislite o čuvanju argumenata kao tuple i njihovom korišćenju u pozivu funkcije.

#4. Povratne vrednosti iz funkcija

U Python-u ćete naići na tuple-ove u povratnim vrednostima iz funkcija. Kada vratite više vrednosti iz funkcije, Python ih implicitno vraća kao tuple.

Razmotrite sledeću funkciju return_even():

    def return_even(num):
      even = [i for i in range(num) if (i%2==0)]
      return even,len(even)
  
  • Kao argument uzima broj num
  • Vraća listu parnih brojeva u intervalu [0,num) i dužinu te liste.

Postavimo vrednost num na 20 i pozovimo funkciju.

    num = 20
  

Pozivanje return_even() vraća dve vrednosti u tuple-u. Možete pozvati funkciju type() sa pozivom funkcije kao argumentom verifikacije.

    type(return_even(num)) # <class 'tuple'>
  

Možete odštampati povratnu vrednost da biste proverili da li je to tuple koji sadrži listu parnih brojeva kao prvi element i dužinu liste kao drugi element.

    print(return_even(num))
    # ([0, 2, 4, 6, 8, 10, 12, 14, 16, 18], 10)
  

Pošto postoje dva elementa u tuple-u, možete ih raspakovati u dve promenljive, kao što je prikazano ispod.

    even_nums, count = return_even(num)

    print(even_nums)
    print(count)

    # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
    # 10
  

Zaključak

Nadam se da je ovaj vodič pružio sveobuhvatno poređenje Python tuple-a i liste.

Hajde da završimo vodič kratkim rezimeom:

  • Lista i tuple su ugrađene strukture podataka u Python-u.
  • Sličnosti: iterabilni, podrška za indeksiranje, sečenje, različiti tipovi podataka i operator za testiranje članstva.
  • Ključna razlika: liste su promenljive, a tuple-ovi su nepromenljivi.
  • Ostale razlike: fiksna dužina tuple-a i promenljiva dužina lista, manja veličina u memoriji tuple-ova.
  • Kada treba da koristite tuple-ove? Za nepromenljive kolekcije, ključeve rečnika i argumente funkcija.

Zatim pogledajte Python projekte za vežbu i učenje. Ili naučite metode za uklanjanje duplikata iz Python lista. Srećno učenje! I srećno kodiranje!👩🏽‍💻