Liste 3 - Metodi base

Scarica zip esercizi

Naviga file online

Le liste sono oggetti di tipo list e possiedono dei metodi che permettono di operare su di essi, tra quelli base troviamo:

Metodo

Ritorna

Descrizione

list.append(obj)

None

Aggiunge un nuovo elemento alla fine della lista

list.extend(list)

None

Aggiunge diversi nuovi elementi alla fine della lista

list.insert(int,obj)

None

Aggiunge un nuovo elemento a qualche posizione data

list.pop()

object

Rimuove e ritorna l’elemento all’ultima posizione

list.pop(int)

object

Dato un indice, rimuove e ritorna l’elemento a quella posizione

list.reverse()

None

Inverte l’ordine degli elementi

list.sort()

None

Ordina gli elementi

list.copy()

list

Copia superficialmente la list

“sep”.join(seq) _

str

produce una stringa concatenando tutti gli elementi in seq separati da "sep"

Gli altri sono descritti alla pagina Metodi di ricerca

ATTENZIONE: I METODI DELLE LISTE *MODIFICANO* LA LISTA SU CUI VENGONO CHIAMATI !

Solitamente, quando chiami un metodo di una lista (l’oggetto a sinistra del punto .), MODIFICHI la lista stessa (diversamente dai metodi sulle stringhe che generano sempre una nuova stringa senza cambiare l’originale)

ATTENZIONE: I METODI DELLE LISTE *NON* RITORNANO NULLA!

Quasi sempre ritornano l’oggetto None (diversamente da quelli delle stringhe che ritornano sempre una nuova stringa)

Che fare

  1. scompatta lo zip in una cartella, dovresti ottenere qualcosa del genere:

lists
    lists1.ipynb
    lists1-sol.ipynb
    lists2.ipynb
    lists2-sol.ipynb
    lists3.ipynb
    lists3-sol.ipynb
    lists4.ipynb
    lists4-sol.ipynb
    lists4.ipynb
    lists5-chal.ipynb
    jupman.py

ATTENZIONE: Per essere visualizzato correttamente, il file del notebook DEVE essere nella cartella szippata.

  1. apri il Jupyter Notebook da quella cartella. Due cose dovrebbero aprirsi, prima una console e poi un browser. Il browser dovrebbe mostrare una lista di file: naviga la lista e apri il notebook lists3.ipynb

  2. Prosegui leggendo il file degli esercizi, ogni tanto al suo interno troverai delle scritte ESERCIZIO, che ti chiederanno di scrivere dei comandi Python nelle celle successive.

Scorciatoie da tastiera:

  • Per eseguire il codice Python dentro una cella di Jupyter, premi Control+Invio

  • Per eseguire il codice Python dentro una cella di Jupyter E selezionare la cella seguente, premi Shift+Invio

  • Per eseguire il codice Python dentro una cella di Jupyter E creare una nuova cella subito dopo, premi Alt+Invio

  • Se per caso il Notebook sembra inchiodato, prova a selezionare Kernel -> Restart

Metodo append

Possiamo MODIFICARE una lista aggiungendo un elemento alla volta usando il metodo append.

Supponiamo di partire da una lista vuota:

[2]:
la = []

Se vogliamo aggiungere come elemento il numero 50, possiamo scrivere così:

[3]:
la.append(50)

Notiamo che la lista che abbiamo creato inizialmente risulta MODIFICATA:

[4]:
la
[4]:
[50]

ATTENZIONE: la.append(50) non ha restituito NULLA !!!!

Guarda bene l’output della cella con l’istruzione la.append(50), noterai che non c’è proprio niente. Questo perchè lo scopo di append è MODIFICARE la lista su cui viene chiamato, NON generare nuove liste.

Aggiungiamo un’altro numero alla fine della lista:

[5]:
la.append(90)
[6]:
la
[6]:
[50, 90]
[7]:
la.append(70)
[8]:
la
[8]:
[50, 90, 70]

Riguardiamoci cosa è successo in Python Tutor:

[9]:
# AFFINCHE' PYTHON TUTOR FUNZIONI, RICORDATI DI ESEGUIRE QUESTA CELLA con Shift+Invio
#   (basta eseguirla una volta sola, la trovi anche all'inizio di ogni foglio)

import jupman
[10]:
la = []
la.append(50)
la.append(90)
la.append(70)

jupman.pytut()
[10]:
Python Tutor visualization

Nota come ad espandersi sia sempre la stessa zona di memoria gialla associata alla variabile la.

Abbiamo detto che il metodo append non ritorna nulla, cerchiamo di specificare meglio. Nella tabella dei metodi, è presente una colonna chiamata Ritorna. Se vai a vedere, per quasi tutti i metodi incluso append è indicato che viene ritornato None.

None è l’oggetto più noioso di Python, perchè letteralmente significa niente. Cosa si può fare con niente? Ben poco, così poco che Jupyter quando si ritrova come risultato un oggetto None non lo stampa nemmeno. Proviamo a inserire direttamente None in una cella, vedrai che non verrà riportato nell’output della cella:

[11]:
None

Un modo per forzare la stampa è usare il comando print:

[12]:
print(None)
None

ESERCIZIO: Qual’è il tipo dell’oggetto None? Scoprilo usando la funzione type

Mostra soluzione
[13]:
# scrivi qui


Proviamo a ripetere cosa succede con append. Se chiami il metodo append su una lista, append MODIFICA silenziosamente la lista, e RITORNA come risultato di essere stato chiamato l’oggetto None. Dato che Jupyter ritiene questo oggetto non interessante, non lo stampa nemmeno come risultato.

Cerchiamo di esplicitare meglio questo misterioso None. Se è vero che append lo produce come risultato di essere chiamato, vuol dire che possiamo associare questo risultato a qualche variabile. Proviamo ad associarlo alla variabile x:

[14]:
la = []
x = la.append(70)

Ora, se tutto è andato come abbiamo scritto, append dovrebbe aver modificato la lista:

[15]:
la
[15]:
[70]

e alla variabile x dovrebbe essere associato None. Quindi, se chiediamo a Jupyter di mostrare il valore associato ad x e se quel valore è None, non dovremmo vedere nulla:

[16]:
x

notiamo che non c’è nessun output nella cella, pare che siamo davvero in presenza di None. Forziamo la stampa con il comando print:

[17]:
print(x)
None

Eccolo ! Probabilmente sarai un po’ confuso da tutto ciò, quindi proviamo a rivedere bene che succede in Python Tutor:

[18]:
la = []
x = la.append(70)
print("la è", la)
print("x è ", x)

jupman.pytut()
la è [70]
x è  None
[18]:
Python Tutor visualization

Qual’è il succo di tutto questo discorso?

RIUSARE IL RISULTATO DI CHIAMATE AI METODI DELLE LISTE E’ QUASI SEMPRE UN ERRORE !!!!

Dato che chiamare i metodi delle lista ci ritorna None, che è un oggetto ‘inutile’, tentare di riusarlo produrrà quasi sicuramente un errore

ESERCIZIO: Costruisci una lista aggiungendo un elemento alla volta con il metodo append. Aggiungi gli elementi 77, "prova", [60,93] con tre chiamate ad append, ed infine stampa la lista.

Dopo il tuo codice, dovresti vedere [77, 'prova', [60, 93]]

Mostra soluzione
[19]:

la = [] # scrivi qui

DOMANDA: Il codice seguente:

la = []
la.append(80,70,90)
  1. produce un errore (quale?)

  2. modifica la lista (come?)

Mostra risposta

DOMANDA: Il codice seguente:

la = []
la.append(80).append(90)
  1. produce un errore

  2. aggiunge a la i numeri 80 e 90

Mostra risposta

DOMANDA: torniamo brevemente alle stringhe. Guarda il codice seguente (se non ti ricordi cosa fanno i metodi delle stringhe guarda qua):

sa = '    trento    '
sb = sa.strip().capitalize()
print(sb)
  1. produce un errore (quale?)

  2. cambia sa (come?)

  3. stampa qualcosa (cosa?)

Mostra risposta

DOMANDA: Guarda questo codice. Stamperà qualcosa alla fine? O produrrà un errore?

[20]:

la = [] lb = [] la.append(lb) lb.append(90) lb.append(70) print(la)
Mostra risposta

Esercizio - accrescere una lista 1

Data la lista la di dimensione fissa 7, scrivi del codice per crescere la lista vuota lb così che contenga solo gli elementi di la a indici pari (0, 2, 4, …).

  • Il tuo codice dovrebbe funzionare per qualunque lista la di dimensione fissa 7

#   0 1 2 3 4 5 6
la=[8,4,3,5,7,3,5]
lb=[]

Dopo il tuo codice, dovresti ottenere:

>>> print(lb)
[8,3,7,5]
Mostra soluzione
[21]:

# 0 1 2 3 4 5 6 la=[8,4,3,5,7,3,5] lb=[] # scrivi qui

Metodo extend

Prima con append abbiamo visto come accrescere una lista un elemento alla volta.

E se volessimo aggiungere in un colpo solo parecchi elementi, magari presi da un’altra lista? Come potremmo fare?

Dovremmo usare il metodo extend, che MODIFICA la lista su cui è chiamato aggiungendo tutti gli elementi trovati nella sequenza presa in input.

[22]:
la = [70,30,50]
[23]:
lb = [40,90,30,80]
[24]:
la.extend(lb)
[25]:
la
[25]:
[70, 30, 50, 40, 90, 30, 80]
[26]:
lb
[26]:
[40, 90, 30, 80]

Nell’esempio qua sopra, extend è chiamato sulla variabile la, e come parametro gli abbiamo passato lb

ATTENZIONE: la è MODIFICATA, invece la sequenza che gli abbiamo passato tra le parentesi tonde no (lb nell’esempio)!

DOMANDA: l’esecuzione del metodo extend ritorna qualcosa? Cosa vedi nell’output della cella la.extend(lb) ?

Mostra risposta

Verifichiamo meglio cosa è successo con Python Tutor:

[27]:
la = [70,30,50]
lb = [40,90,30,80]
la.extend(lb)

jupman.pytut()
[27]:
Python Tutor visualization

DOMANDA: Guarda questo codice. Quali saranno i valori associati alle variabili la ,lb e x dopo la sua esecuzione?

[28]:

la = [30,70,50] lb = [80,40] x = la.extend(lb) print('la è ', la) print('lb è ', lb) print('x è ', x)
Mostra risposta

Estendere con sequenze

Abbiamo detto che tra le parentesi tonde extend può prendere una sequenza generica, non solo liste. Questo vuol dire che possiamo anche passargli una stringa. Per esempio:

[29]:
la = [70,60,80]

s = "ciao"

la.extend(s)
[30]:
la
[30]:
[70, 60, 80, 'c', 'i', 'a', 'o']

Dato che stringa è una sequenza di caratteri, extend ha preso ciascuno di questi elementi e li ha aggiunti a la

DOMANDA: il valore associato alla variabile s è stato modificato?

Mostra risposta

DOMANDA: Il codice seguente:

la = [60,50]
la.extend(70,90,80)
  1. produce un errore (quale?)

  2. modifica la (come?)

Mostra risposta

DOMANDA: Se questo codice viene eseguito, che succede?

sa = "ciao"
sb = "mondo"
sa.extend(sb)
  1. sa viene modificata (come?)

  2. otteniamo un errore (quale?)

Mostra risposta

DOMANDA: Se questo codice viene eseguito, che succede?

la = [1,2,3]
lb = [4,5]
lc = [6,7,8]

la.extend(lb).extend(lc)
  1. la diventa [1,2,3,4,5,6,7,8]

  2. un errore (quale?)

  3. la diventa [1,2,3,4,5] e un errore(quale?)

Mostra risposta

Esercizio: accrescere una lista 2

Date due liste la ed lb e un elemento x, scrivi del codice che MODIFICA la in modo che la contenga alla fine l’elemento x seguito da tutti gli elementi di lb

  • NOTA 1: il tuo codice dovrebbe funzionare con qualunque la ed lb

  • NOTA 2: id è una funzione di Python che associa ad ogni regione di memoria un identificativo numerico univoco. Se provi a stampare id(la) prima di modificare la e id(la) dopo, dovresti ottenere esattamente lo stesso id. Se ne ottieni uno diverso, significa che hai generato una lista interamente nuova. In ogni caso, verifica che funzioni in Python Tutor.

la = [5,9,2,4]
lb = [7,1,3]
x = 8

Dovresti ottenere:

>>> print(la)
[5,9,2,4,8,7,1,3]
>>> print(lb)
[7,1,3]
>>> print(x)
8
Mostra soluzione
[31]:

la = [5,9,2,4] lb = [7,1,3] x = 8 # scrivi qui

Esercizio - zslice

Scrivi del codice che date due liste la (di almeno 3 elementi) e lb, MODIFICA lb in modo che vi siano aggiunti i primi 3 elementi di la seguiti dagli ultimi 3 elementi di la

  • il tuo codice deve funzionare con qualsiasi lista

  • usa extend e le slice

la = ['a','b','c','d','e','f','g','h','i','l','m','n','o']
lb = ['z']

Dovresti ottenere:

>>> print(la)
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'l', 'm', 'n', 'o']
>>> print(lb)
['z', 'a', 'b', 'c', 'm', 'n', 'o']
Mostra soluzione
[32]:

la = ['a','b','c','d','e','f','g','h','i','l','m','n','o'] lb = ['z'] # scrivi qui

Esercizio - vedunazeblag

Scrivi del codice che data una lista di tre stringhe parole e una lista vuota la, riempie la con tutti i primi 3 caratteri di ogni stringa in parole.

  • il tuo codice deve funzionare con qualsiasi lista di 3 stringhe

  • usa le slice

Esempio - data:

parole = ["vedo", "una", "zebra", "laggiù"]
la = []

il tuo codice deve mostrare

>>> print(t)
['v', 'e', 'd', 'u', 'n', 'a', 'z', 'e', 'b', 'l', 'a', 'g']
Mostra soluzione
[33]:

parole = ["vedo", "una", "zebra", "laggiù"] la = [] # scrivi qui

Metodo insert

insert MODIFICA la lista inserendo un elemento ad uno specifico indice - tutti gli elementi a partire da quell’indice vengono spostati in avanti di una posizione

[34]:
     #0 1 2 3
la = [6,7,8,9]
[35]:
la.insert(2,55)  # inserisce il numero 55 all'indice 2
[36]:
la
[36]:
[6, 7, 55, 8, 9]
[37]:
la.insert(0,77)  # inserisce il numero 77 all'indice 0
[38]:
la
[38]:
[77, 6, 7, 55, 8, 9]

Possiamo inserire dopo la fine:

[39]:
la.insert(6,88)  # inserisce il numero 88 all'indice 6
[40]:
la
[40]:
[77, 6, 7, 55, 8, 9, 88]

Nota che se sforiamo con l’indice, l’elemento viene comunque messo alla fine e non vengono create celle vuote:

[41]:
la.insert(1000,99)  # in questo caso inserisce il numero 99 all'indice 7

DOMANDA: Data una lista qualsiasi x, questo codice cosa produce? Possiamo riscriverlo in un’altra maniera?

x.insert(len(x),66)
  1. produce una nuova lista (quale?)

  2. modifica x (come?)

  3. un errore

Mostra risposta

DOMANDA: Il seguente codice, cosa produce?

la = [3,4,5,6]
la.insert(0,[1,2])
print(la)
  1. stampa [1,2,3,4,5,6]

  2. un errore (quale?)

  3. qualcos’altro (cosa?)

Mostra risposta

DOMANDA: Il seguente codice cosa produce?

la = [4,5,6]
la.insert(0,1,2,3)
print(la)
  1. stampa [1,2,3,4,5,6]

  2. un errore (quale?)

  3. qualcos’altro (cosa?)

Mostra risposta

DOMANDA: Il seguente codice cosa produce?

la = [4,5,6]
lb = la.insert(0,3)
lc = lb.insert(0,2)
ld = lc.insert(0,1)
print(ld)
  1. stampa [1,2,3,4,5,6]

  2. un errore (quale?)

  3. qualcos’altro (cosa?)

Mostra risposta

Esercizio - insertando

Data la lista:

la = [7,6,8,5,6]

scrivi del codice che la MODIFICA usando solo chiamate a insert. Dopo il tuo codice, la deve apparire così:

>>> print(la)
[7, 70, 90, 6, 8, 80, 5, 6, 50]
Mostra soluzione
[42]:

la = [7,6,8,5,6] # scrivi qui

ATTENZIONE: chiamare insert è molto più lento di append !!

Una chiamata ad insert riscrive tutte le celle successive a quella dell’inserimento, mentre invece append aggiunge una cella e basta. Dato che il computer è veloce, molto spesso non ci si accorge della differenza, ma quando possibile, e specialemente se devi scrivere programmi che operano su grandi quantità di dati, prova a scrivere il codice usando append invece di insert.

Esercizio - insappend

Questo codice prende come input una lista vuota la e una lista di numeri lb. Cerca di capire cosa fa, e riscrivilo usando degli append.

[43]:
la = []
lb = [7,6,9,8]
la.insert(0,lb[0]*2)
la.insert(0,lb[1]*2)
la.insert(0,lb[2]*2)
la.insert(0,lb[3]*2)
print(la)
[16, 18, 12, 14]
Mostra soluzione
[44]:

la = [] lb = [7,6,9,8] # scrivi qui

Metodo pop

Il metodo pop se chiamato senza argomenti rimuove l’ultimo elemento (MODIFICANDO la lista) e lo ritorna:

[45]:
cesta = ['melone','fragola', 'anguria']
[46]:
cesta.pop()
[46]:
'anguria'
[47]:
cesta
[47]:
['melone', 'fragola']
[48]:
cesta.pop()
[48]:
'fragola'
[49]:
cesta
[49]:
['melone']

Visto che l’ultimo elemento è ritornato dalla pop, possiamo assegnarlo ad una variabile:

[50]:
frutto = cesta.pop()

Nota che non vediamo più nessun risultato stampato perchè l’elemento ritornato è stato assegnato alla variabile frutto:

[51]:
frutto
[51]:
'melone'

Constatiamo anche che cesta è stata MODIFICATA:

[52]:
cesta
[52]:
[]

Chiamare ulteriormente pop su una lista vuota genera un’errore:

cesta.pop()
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-67-086f38c9fbc0> in <module>()
----> 1 cesta.pop()

IndexError: pop from empty list

Opzionalmente, per rimuovere un elemento ad una specifica posizione possiamo passare a pop un indice da 0 INCLUSO alla lunghezza della lista ESCLUSA:

[53]:
#           0           1             2        3
attrezzi = ['martello', 'cacciavite', 'pinza', 'martello']
[54]:
attrezzi.pop(2)
[54]:
'pinza'
[55]:
attrezzi
[55]:
['martello', 'cacciavite', 'martello']

DOMANDA: Guarda i frammenti di codice seguenti, e per ciascuno cerca di indovinare che risultato produce (o se risulta in un errore).

  1. la = ['a']
    print(la.pop())
    print(la.pop())
    
  2. la = [4,3,2,1]
    print(la.pop(4))
    print(la)
    
  3. la = [1,2,3,4]
    print(la.pop(3))
    print(la)
    
  4. la = [1,2,3,4]
    print(la.pop(-1))
    print(la)
    
  5. s = 'grezzo'
    print(s.pop())
    print(s)
    
  6. la = ['molto', 'grezzo']
    print(la.pop())
    print(la)
    
  7. la = ['a', ['a']]
    print(la.pop())
    print(la)
    

Esercizio - popcorn

Data una lista corn di esattamente 4 caratteri, scrivi del codice che trasferisce in ordine inverso tutti i caratteri da corn ad un’altra lista scatola che inizialmente è vuota.

  • NON usare metodi come reverse o funzioni come reversed

  • Il tuo codice deve funzionare con qualsiasi lista corn di 4 elementi

Esempio - date:

corn = ['t','o','r','o']
scatola = []

dopo il tuo codice, deve risultare:

>>> print(corn)
[]
>>> print(scatola)
['o','r','o','t']
Mostra soluzione
[56]:
corn = ['t','o','r','o']
scatola = []

# scrivi qui


Esercizio - zonzo

Data una lista la contenente dei caratteri, e una lista lb contente esattamente due posizioni ordinate in modo crescente , scrivi del codice che elimina da la i caratteri alle posizioni specificate in lb.

  • ATTENZIONE: chiamando la pop la prima volta MODIFICHERAI la, quindi l’indice del secondo elemento da eliminare andrà opportunamente aggiustato !

  • NON creare nuove liste, quindi niente righe che iniziano con la =

  • Il tuo codice deve funzionare per qualsiasi la, e qualsiasi lb da due elementi

Esempio - dati:

#      0   1   2   3   4
la = ['z','o','n','z','o']
lb = [2,4]

alla posizione 2 in la troviamo la n e alla 4 la o, quindi dopo il tuo codice dovrà risultare:

>>> print(la)
['z', 'o', 'z']
Mostra soluzione
[57]:

# 0 1 2 3 4 la = ['z','o','n','z','o'] lb = [2,4] # scrivi qui

Metodo reverse

Il metodo reverse MODIFICA la lista su cui è chiamato invertendo l’ordine degli elementi.

Vediamo un esempio:

[58]:
la = [7,6,8,4]
[59]:
la.reverse()
[60]:
la
[60]:
[4, 8, 6, 7]

ATTENZIONE: reverse NON RITORNA NULLA!

Per essere precisi, ritorna None

[61]:
lb = [7,6,8,4]
[62]:
x = lb.reverse()
[63]:
print(x)
None
[64]:
print(lb)
[4, 8, 6, 7]

DOMANDA: Il codice seguente che effetto produce?

s = "transatlantico"
s.reverse()
print(s)
  1. un errore (quale?)

  2. stampa la stringa rovesciata

Mostra risposta

DOMANDA: Se x è una lista qualsiasi, che effetto produce il codice seguente?

x.reverse().reverse()
  1. cambia la lista (come?)

  2. non cambia la lista

  3. genera un errore (quale?)

Mostra risposta

Esercizio - come va?

Scrivi del codice che date due liste la e lb, MODIFICA la aggiungendogli tutti gli elementi di lb e rovesciando poi l’intera lista.

  • il tuo codice deve funzionare per qualunque la e lb

  • NON modificare lb

Esempio - dati:

la = ['c','o','m','e']
lb = ['v','a','?']

Dopo il tuo codice, deve stampare:

>>> print('la=',la)
la= ['?', 'a', 'v', 'e', 'm', 'o', 'c']
>>> print('lb=',lb)
lb= ['v', 'a', '?']
Mostra soluzione
[65]:

la = ['c','o','m','e'] lb = ['v','a','?'] # scrivi qui

Esercizio - cose preziose

Date due liste la e lb, scrivi del codice che STAMPA una lista con gli elementi di la e lb in ordine invertito

  • NON modificare la e NON modificare lb

  • il tuo codice deve funzionare per qualsiasi lista la e lb

Esempio - dati

la = ['c', 'o', 's', 'e']
lb = ['p', 'r', 'e', 'z', 'i', 'o', 's', 'e']

dopo il tuo codice deve stampare

['e', 's', 'o', 'i', 'z', 'e', 'r', 'p', 'e', 's', 'o', 'c']
Mostra soluzione
[66]:

la = ['c', 'o', 's', 'e'] lb = ['p', 'r', 'e', 'z', 'i', 'o', 's', 'e'] # scrivi qui

Esercizio - potenze

Il codice seguente usa degli insert che come già detto non sono molto efficienti. Cerca di capire cosa fa, e riscrivilo usando solo append e reverse

  • il tuo codice deve funzionare per qualsiasi valore di x

[67]:
x = 2
la = [x]
la.insert(0,la[0]*2)
la.insert(0,la[0]*2)
la.insert(0,la[0]*2)
la.insert(0,la[0]*2)
print(la)
[32, 16, 8, 4, 2]
Mostra soluzione
[68]:

x = 2 la = [x] # scrivi qui

Metodo sort

Se una lista contiene elementi omogenei, è possibile ordinarla rapidamente con il metodo sort, che MODIFICA la lista su cui viene chiamato:

[69]:
la = [8,6,7,9]
[70]:
la.sort()  # NOTA: sort non ritorna nulla !!!
[71]:
la
[71]:
[6, 7, 8, 9]

Anche le stringhe sono ordinabili:

[72]:
lb = ['Boccaccio', 'Alighieri', 'Manzoni', 'Leopardi']
[73]:
lb.sort()
[74]:
lb
[74]:
['Alighieri', 'Boccaccio', 'Leopardi', 'Manzoni']

Una lista con elementi non comparabili tra loro non è ordinabile, e Python si lamenterà:

[75]:
lc = [3,4,'cavoli',7,'patate']
>>> lc.sort()

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-288-0cabfae30939> in <module>
----> 1 lc.sort()

TypeError: '<' not supported between instances of 'str' and 'int'

Criteri di ordinamento

Se hai bisogni particolari, per esempio una lista di stringhe 'nome cognome' che vuoi ordinare in base al solo cognome, potresti usare il parametro key con le funzioni lambda, vedere documentazione di Python.

Esercizio - numlist

Data la lista

la = [10, 60, 72, 118, 11, 71, 56, 89, 120, 175]
  1. trova il min, max e valore mediano (SUGGERIMENTO: ordinala ed estrai i giusti valori)

  2. crea una lista solo con gli elementi a indici pari (per es [10, 72, 11, ..], nota che “..” indica che lista non è completa !) e ricalcola i valori di min, max e mediana

  3. rifai lo stesso con gli elementi ad indici dispari (per es [60, 118,..])

Dovresti ottenere:

la: [10, 60, 72, 118, 11, 71, 56, 89, 120, 175]
pari: [10, 72, 11, 56, 120]
dispari: [60, 118, 71, 89, 175]

ordinati:   [10, 11, 56, 60, 71, 72, 89, 118, 120, 175]
ordinati pari:   [10, 11, 56, 72, 120]
ordinati dispari:   [60, 71, 89, 118, 175]

la: Min:  10  Max. 175  Median:  72
pari: Min:  10  Max. 120  Median:  56
dispari: Min:  60  Max. 175  Median:  89
Mostra soluzione
[76]:


la = [10, 60, 72, 118, 11, 71, 56, 89, 120, 175] # scrivi qui

Metodo join - da liste a stringhe

Data una stringa che funge da separatore, e una sequenza come per esempio una lista la contenente solo stringhe, è possibile concatenarle in una sola stringa (nuova) con il metodo join:

[77]:
la = ['Quando', 'fuori', 'piove']

'SEPARATORE'.join(la)
[77]:
'QuandoSEPARATOREfuoriSEPARATOREpiove'

Come separatore possiamo mettere qualunque carattere, come uno spazio:

[78]:
' '.join(la)
[78]:
'Quando fuori piove'

Nota che la lista originale non viene modificata:

[79]:
la
[79]:
['Quando', 'fuori', 'piove']

DOMANDA: Questo codice cosa produce?

''.join(['a','b','c']).upper()
  1. un errore (quale?)

  2. una stringa (quale?)

  3. una lista (quale?)

Mostra risposta

DOMANDA: Questa codice cosa produce?

'A'.join('porto')
  1. una stringa (quale?)

  2. un errore (quale?)

  3. una lista (quale?)

Mostra risposta

DOMANDA: Questo codice cosa produce?

'\''.join('mmmm')
  1. un errore (quale?)

  2. una stringa (quale?)

Mostra risposta

DOMANDA: Data una stringa qualsiasi s e una lista di stringhe qualsiasi la di almeno due elementi, il seguente codice darà sempre lo stesso risultato - quale ? (pensaci, e se non sai rispondere prova a mettere dei valori a caso di s e la)

len(s) <= len(s.join(la))
  1. un errore (quale?)

  2. una stringa (quale?)

  3. altro (cosa?)

Mostra risposta

Esercizio - barzoletta

Data la stringa:

sa = 'barzoletta'

scrivi del codice che crea una NUOVA stringa sb cambiando la stringa originale in modo che risulti:

>>> print(sb)
'barzelletta'
  • USA il metodo insert e riassegnazione di celle

  • NOTA: non puoi usarle su una stringa, perchè è IMMUTABILE - dovrai quindi prima convertire la stringa in una lista

Mostra soluzione
[80]:


sa = 'barzoletta' # scrivi qui

Esercizio - dub dab dib dob

Scrivi del codice che data una lista di stringhe la, associa alla variabile s una stringa con le stringhe concatenate separate da virgole e uno spazio

Esempio:

Data

la = ['dub', 'dab','dib', 'dob']

dopo il tuo codice, dovresti ottenere questi risultati:

>>> print(s)
dub, dab, dib, dob
>>> len(s)
18
Mostra soluzione
[81]:

la = ['dub', 'dab','dib', 'dob'] # scrivi qui

Esercizio - ghirigori

Data una lista di stringhe la e una lista di tre separatori seps, scrivi del codice che stampa gli elementi di la separati dal primo separatore, seguiti dal secondo separatore, seguiti dagli elementi di la separati dal terzo separatore.

  • il tuo codice deve funzionare con qualunque lista la e seps

Esempio: dati

la = ['ghi','ri','go','ri']
seps = [',','_','+']

Dopo il tuo codice, deve stampare:

ghi,ri,go,ri_ghi+ri+go+ri
Mostra soluzione
[82]:

la = ['ghi','ri','go','ri'] seps = [',','_','+'] # scrivi qui

Esercizio - welldone

Data la lista:

la = ["walnut", "eggplant", "lemon", "lime", "date", "onion", "nectarine", "endive" ]:
  1. Crea un’altra lista (chiamala nuova) contenente il primo carattere di ogni elemento di la

  2. Aggiungi uno spazio a nuova all aposizione 4 e attacca un punto esclamativo ('!') alla fine

  3. Stampa la lista

  4. Stampa il contenuto della lista unendo tutti gli elementi con uno spazio vuoto (per es usa il metodo join: "".join(nuova))

Dovresti ottenere:

['w', 'e', 'l', 'l', ' ', 'd', 'o', 'n', 'e', '!']

 well done!
Mostra soluzione
[83]:

la = ["walnut", "eggplant", "lemon", "lime", "date", "onion", "nectarine", "endive" ] # scrivi qui

Metodo copy

Se vogliamo copiare una struttura di dati mutabili, abbiamo a disposizione il metodo .copy(), che effettua una cosiddetta copia di superficie (shallow copy). Vediamo meglio cosa vuol dire.

Iniziamo da un caso semplice, per esempio una lista di oggetti immutabili come le stringhe e visualizziamo in PythonTutor:

[84]:
satelliti = ["Hubble", "Sputnik 1"]

copia = satelliti.copy()

jupman.pytut()
[84]:
Python Tutor visualization

Vediamo chiaramente come sia stata creata una regione di memoria completamente nuova. Se proviamo a modificare successivamente la copia, noteremo che l’originale satelliti non viene alterato:

[85]:
satelliti = ["Sputnik 1", "Hubble"]

copia = satelliti.copy()

copia.append("James Webb")

jupman.pytut()
[85]:
Python Tutor visualization

copy è superficiale

Fin qua, non abbiamo notato problemi particolari. Ma cosa succede se proviamo copy() su una lista che contiene altre liste, in altre parole, elementi a loro volta mutabili, e poi proviamo a mutare una delle due?

[86]:
listonaA = [ ['Fai', 'attenzione'],
             ['a', 'dove'],
             ['puntano', 'le', 'frecce']
]

listonaB = listonaA.copy()

listonaA[2][0] = 'OCCHIO!'  # scriviamo nell'originale...

print(listonaA)
print(listonaB)

jupman.pytut()
[['Fai', 'attenzione'], ['a', 'dove'], ['OCCHIO!', 'le', 'frecce']]
[['Fai', 'attenzione'], ['a', 'dove'], ['OCCHIO!', 'le', 'frecce']]
[86]:
Python Tutor visualization

Notiamo che abbiamo due listone le cui celle puntano a delle sottoliste condivise, quindi scrivendo in una sotto cella di listonaA di fatto finiamo anche per scrivere in listonaB!

In altre parole, .copy() effettua sulo una cosiddetta ‘copia in superficie’ (shallow copy), per la ‘copia in profondità’ (deep copy) serviranno altri sistemi!

Funzione deepcopy

Per evitare problemi di condivisione possiamo usare la cosidetta ‘copia in profondità’ (deep copy), disponibile nella funzione deepcopy del modulo copy.

ATTENZIONE: deepcopy NON è un metodo delle liste!

Riproviamo l’esempio con copy.deepcopy, adesso otterremo veramente strutture dati completamente distinte:

[87]:
# prima importiamo `copy`, che è un MODULO PYTHON
import copy

listonaA = [ ['Fate', 'attenzione'],
             ['a', 'dove'],
             ['puntano', 'le', 'frecce']
]

# poi chiamiamo la sua funzione deepcopy, passandogli il parametro `listonaA`:
listonaB = copy.deepcopy(listonaA)
listonaA[2][0]  = 'OCCHIO!' # scriviamo nell'originale...

print(listonaA)
print(listonaB)

jupman.pytut()
[['Fate', 'attenzione'], ['a', 'dove'], ['OCCHIO!', 'le', 'frecce']]
[['Fate', 'attenzione'], ['a', 'dove'], ['puntano', 'le', 'frecce']]
[87]:
Python Tutor visualization

Prosegui

Continua con Liste 4 - metodi di ricerca

[ ]: