Ordinamento Python

Il modo più semplice per effettuare l'ordinamento è mediante la funzione "Ordinata(list)", che crea un elenco e restituisce un nuovo elenco con tali elementi in ordine. L'elenco originale non è stato modificato.

  a = [5, 1, 4, 3]
  print(sorted(a))  ## [1, 3, 4, 5]
  print(a)  ## [5, 1, 4, 3]

È più comune passare un elenco alla funzione order(), ma in realtà può essere utilizzato come input qualsiasi tipo di raccolta iterabile. Il vecchio metodo list.sort() è un'alternativa descritta di seguito. La funzione order() sembra più facile da utilizzare rispetto a sort(), quindi ti consiglio di usare order().

La funzione order() può essere personalizzata mediante argomenti facoltativi. L'argomento facoltativo ordinare() reverse=True, ad esempio order(list, reverse=True), consente di ordinare all'indietro.

  strs = ['aa', 'BB', 'zz', 'CC']
  print(sorted(strs))  ## ['BB', 'CC', 'aa', 'zz'] (case sensitive)
  print(sorted(strs, reverse=True))   ## ['zz', 'aa', 'CC', 'BB']

Ordinamento personalizzato con chiave=

Per un ordinamento personalizzato più complesso, order() richiede una funzione "key=" facoltativa che specifica una funzione "chiave" che trasforma ogni elemento prima del confronto. La funzione chiave acquisisce un valore e restituisce un valore, mentre il valore "proxy" restituito viene utilizzato per i confronti all'interno dell'ordinamento.

Ad esempio, se utilizzi un elenco di stringhe, se specifichi key=len (la funzione len() integrata), le stringhe vengono ordinate in base alla lunghezza, dalla più breve alla più lunga. L'ordinamento chiama len() per ogni stringa per ottenere l'elenco dei valori di lunghezza proxy, quindi esegue l'ordinamento in base a questi valori proxy.

  strs = ['ccc', 'aaaa', 'd', 'bb']
  print(sorted(strs, key=len))  ## ['d', 'bb', 'ccc', 'aaaa']

chiamata ordinata con key=len

Oppure, specificare "str.lower" come funzione chiave è un modo per forzare l'ordinamento a trattare le lettere maiuscole e le minuscole allo stesso modo:

  ## "key" argument specifying str.lower function to use for sorting
  print(sorted(strs, key=str.lower))  ## ['aa', 'BB', 'CC', 'zz']

Puoi anche passare il tuo MyFn come funzione chiave, come segue:

  ## Say we have a list of strings we want to sort by the last letter of the string.
  strs = ['xc', 'zb', 'yd' ,'wa']

  ## Write a little function that takes a string, and returns its last letter.
  ## This will be the key function (takes in 1 value, returns 1 value).
  def MyFn(s):
    return s[-1]

  ## Now pass key=MyFn to sorted() to sort by the last letter:
  print(sorted(strs, key=MyFn))  ## ['wa', 'zb', 'xc', 'yd']

Per un ordinamento più complesso, come l'ordinamento per cognome e poi per nome, puoi utilizzare le funzioni itemgetter o attrgetter come:

  from operator import itemgetter

  # (first name, last name, score) tuples
  grade = [('Freddy', 'Frank', 3), ('Anil', 'Frank', 100), ('Anil', 'Wang', 24)]
  sorted(grade, key=itemgetter(1,0))
  # [('Anil', 'Frank', 100), ('Freddy', 'Frank', 3), ('Anil', 'Wang', 24)]

  sorted(grade, key=itemgetter(0,-1))
  #[('Anil', 'Wang', 24), ('Anil', 'Frank', 100), ('Freddy', 'Frank', 3)]

Metodo sort()

In alternativa a order(), il metodo sort() in un elenco ordina l'elenco in ordine crescente, ad esempio list.sort(). Il metodo sort() cambia l'elenco sottostante e restituisce None, quindi usalo in questo modo:

  alist.sort()            ## correct
  alist = blist.sort()    ## Incorrect. sort() returns None

Quanto riportato sopra è un malinteso molto comune relativo a sort(): *non restituisce* l'elenco ordinato. Il metodo sort() deve essere chiamato in un elenco; non funziona in nessuna raccolta enumerabile (ma la funzione order() di cui sopra funziona su qualsiasi cosa). Il metodo sort() è precedente alla funzione order(), quindi probabilmente lo vedrai nel codice precedente. Il metodo sort() non ha bisogno di creare un nuovo elenco, quindi può essere un po' più veloce nel caso in cui gli elementi da ordinare siano già presenti in un elenco.

Tuple

Una tupla è un raggruppamento di elementi a dimensione fissa, ad esempio una coordinata (x, y). Le tuple sono come gli elenchi, tranne per il fatto che sono immutabili e non cambiano dimensione (le tuple non sono rigorosamente immutabili poiché uno degli elementi contenuti potrebbe essere modificabile). Le tuple svolgono una sorta di ruolo "struct" in Python: un modo conveniente per trasferire un gruppo di valori un po' logico e a dimensione fissa. Una funzione che deve restituire più valori può semplicemente restituire una tupla di valori. Ad esempio, se volessi avere un elenco di coordinate 3 d, la rappresentazione pitone naturale sarebbe un elenco di tuple, in cui ogni tupla ha la dimensione 3 e contiene un gruppo (x, y, z).

Per creare una tupla, elenca semplicemente i valori tra parentesi separati da virgole. La tupla "vuota" è solo una coppia di parentesi vuota. L'accesso agli elementi in una tupla è come in un elenco: len(), [ ], for, in e così via funzionano tutti allo stesso modo.

  tuple = (1, 2, 'hi')
  print(len(tuple))  ## 3
  print(tuple[2])    ## hi
  tuple[2] = 'bye'  ## NO, tuples cannot be changed
  tuple = (1, 2, 'bye')  ## this works

Per creare una tupla di dimensione 1, l'elemento unico deve essere seguito da una virgola.

  tuple = ('hi',)   ## size-1 tuple

La sintassi è un caso divertente, ma la virgola è necessaria per distinguere la tupla dal caso ordinario in cui si inserisce un'espressione tra parentesi. In alcuni casi puoi omettere le parentesi e Python noterà dalle virgole che intendi utilizzare una tupla.

L'assegnazione di una tupla a una tupla di dimensioni identiche di nomi di variabili assegna tutti i valori corrispondenti. Se le tuple non hanno le stesse dimensioni, viene generato un errore. Questa funzionalità è valida anche per gli elenchi.

  (x, y, z) = (42, 13, "hike")
  print(z)  ## hike
  (err_string, err_code) = Foo()  ## Foo() returns a length-2 tuple

(Facoltativo) Elenco competenze

La comprensione degli elenchi è una funzionalità più avanzata che è utile in alcuni casi, ma non è necessaria per gli esercizi e non è qualcosa che devi imparare all'inizio (ad esempio, puoi saltare questa sezione). La comprensione di un elenco è un modo compatto per scrivere un'espressione che si espande in un intero elenco. Supponiamo di avere una lista num [1, 2, 3, 4], ecco la comprensione dell'elenco per calcolare una lista dei loro quadrati [1, 4, 9, 16]:

  nums = [1, 2, 3, 4]

  squares = [ n * n for n in nums ]   ## [1, 4, 9, 16]

La sintassi è [ expr for var in list ]: for var in list appare come un normale ciclo for, ma senza i due punti (:). L'expr alla sua sinistra viene valutata una volta per ogni elemento per fornire i valori per il nuovo elenco. Ecco un esempio di stringhe in cui ogni stringa viene modificata in lettere maiuscole e viene aggiunto "!!!":

  strs = ['hello', 'and', 'goodbye']

  shouting = [ s.upper() + '!!!' for s in strs ]
  ## ['HELLO!!!', 'AND!!!', 'GOODBYE!!!']

Puoi aggiungere un test if a destra del ciclo for per restringere il risultato. Il test if viene valutato per ogni elemento, inclusi solo gli elementi in cui il test è vero.

  ## Select values <= 2
  nums = [2, 8, 1, 6]
  small = [ n for n in nums if n <= 2 ]  ## [2, 1]

  ## Select fruits containing 'a', change to upper case
  fruits = ['apple', 'cherry', 'banana', 'lemon']
  afruits = [ s.upper() for s in fruits if 'a' in s ]
  ## ['APPLE', 'BANANA']

Allenamento: list1.py

Per esercitarti con il materiale di questa sezione, prova problemi successivi in list1.py che utilizzano ordinamento e tuple (negli Esercizi di base).