Stringhe Python

Python ha una classe di stringhe incorporata denominata "str" con molte funzionalità utili (esiste un modulo meno recente chiamato "string", che non dovresti utilizzare). I valori letterali stringa possono essere racchiusi tra virgolette doppie o singole, sebbene le virgolette singole siano più comunemente utilizzate. I valori di escape con barra rovesciata funzionano come di consueto sia all'interno dei valori letterali sia con virgolette singole che con virgolette doppie, ad esempio \n \' \". Un valore letterale di stringa con virgolette può contenere virgolette singole senza errori (ad esempio, "Non l'ho fatto") e, allo stesso modo, le stringhe con virgolette singole possono contenere virgolette doppie. Un valore letterale stringa può estendersi su più righe, ma deve essere presente una barra rovesciata \ alla fine di ogni riga per eseguire l'escape della nuova riga. I valori letterali stringa tra virgolette triple, """ o ''', possono estendersi su più righe di testo.

Le stringhe Python sono "immutabili", il che significa che non possono essere modificate dopo essere state create (anche le stringhe Java utilizzano questo stile immutabile). Poiché le stringhe non possono essere modificate, costruiamo *nuove* stringhe man mano che andiamo a rappresentare i valori calcolati. Quindi, ad esempio, l'espressione ("hello" + "there") prende le due stringhe "hello" e "there" e crea una nuova stringa "hellothere".

È possibile accedere ai caratteri di una stringa usando la sintassi standard [ ] e, come Java e C++, Python usa l'indicizzazione in base zero, quindi se s è "hello" s[1] è "e". Se l'indice è fuori dai limiti della stringa, Python genera un errore. Lo stile Python (a differenza di Perl) prevede l'arresto se non è in grado di capire cosa fare, piuttosto che creare un valore predefinito. La pratica sintassi "sezione" (di seguito) serve anche a estrarre qualsiasi sottostringa da una stringa. La funzione len(string) restituisce la lunghezza di una stringa. La sintassi [ ] e la funzione len() in realtà funzionano con qualsiasi tipo di sequenza: stringhe, elenchi e così via. Python cerca di far funzionare le sue operazioni in modo coerente su diversi tipi. Principiante Python: non usare "len" come nome della variabile per evitare di bloccare la funzione len(). L'operatore "+" può concatenare due stringhe. Nota nel codice riportato di seguito che le variabili non sono pre-dichiarate: devi solo assegnarle e procedere.

  s = 'hi'
  print(s[1])          ## i
  print(len(s))        ## 2
  print(s + ' there')  ## hi there

A differenza di Java, "+" non converte automaticamente numeri o altri tipi in formato stringa. La funzione str() converte i valori in una stringa in modo che possano essere combinati con altre stringhe.

  pi = 3.14
  ##text = 'The value of pi is ' + pi      ## NO, does not work
  text = 'The value of pi is '  + str(pi)  ## yes

Per i numeri, gli operatori standard, +, /, * funzionano come di consueto. Non esiste un operatore ++, ma +=, -= e così via funzionano. Se vuoi la divisione intera, utilizza 2 barre, ad esempio 6 // 5 è 1

La funzione "print" solitamente stampa uno o più elementi Python seguiti da una nuova riga. Un valore letterale stringa "non elaborata" è preceduto da una "r" e passa tutti i caratteri senza uno speciale trattamento delle barre rovesciate, quindi r'x\nx' restituisce la stringa length-4 "x\nx". "print" può richiedere diversi argomenti per modificare il modo in cui stampa gli elementi (vedi la definizione della funzione di stampa python.org), ad esempio impostare "end" su "" per non stampare più una nuova riga al termine della stampa di tutti gli elementi.

  raw = r'this\t\n and that'

  # this\t\n and that
  print(raw)

  multi = """It was the best of times.
  It was the worst of times."""

  # It was the best of times.
  #   It was the worst of times.
  print(multi)

Metodi con stringhe

Di seguito sono riportati alcuni dei metodi con stringhe più comuni. Un metodo è simile a una funzione, ma viene eseguito "su" un oggetto. Se la variabile s è una stringa, il codice s.lower() esegue il metodolower() sull'oggetto stringa e restituisce il risultato (questa idea di metodo in esecuzione su un oggetto è una delle idee di base che compongono la programmazione con oggetti OOP). Di seguito sono riportati alcuni dei metodi con stringhe più comuni:

  • s.lower(), s.upper(): restituisce la versione maiuscola o minuscola della stringa.
  • s.strip(): restituisce una stringa con spazi vuoti rimossi all'inizio e alla fine.
  • s.isalpha()/s.isdigit()/s.isspace()... -- verifica se tutti i caratteri della stringa sono nelle varie classi di caratteri
  • s.startswith('other'), s.endswith('other'): verifica se la stringa inizia o termina con l'altra stringa specificata.
  • s.find('other') . Cerca l'altra stringa specificata (non un'espressione regolare) all'interno di s e restituisce il primo indice in cui inizia o -1 se non viene trovata.
  • s.replace('old', 'new') restituisce una stringa in cui tutte le occorrenze di "old" sono state sostituite da "new"
  • s.split('delim') -- restituisce un elenco di sottostringhe separate dal delimitatore specificato. Il delimitatore non è un'espressione regolare, è solo testo. 'aaa,bbb,cancel'.split(',') -> ['aaa', 'bbb', 'uc']. Come pratico caso speciale, s.split() (senza argomenti) si divide in base a tutti i caratteri di spazio vuoto.
  • s.join(list) -- opposto di split(), unisce gli elementi nell'elenco specificato utilizzando la stringa come delimitatore. ad es. '---'.join(['aaa', 'bbb', 'CC']) -> aaa---bbb---cancel

Una ricerca su Google per "python str" dovrebbe portarti ai metodi stringa python.org ufficiali che elencano tutti i metodi str.

Python non ha un tipo di carattere separato. Invece, un'espressione come s[8] restituisce una stringa-length-1 contenente il carattere. Con quella stringa-length-1, gli operatori ==, <=, ... funzionano tutti come ci si aspetterebbe, quindi per lo più non è necessario sapere che Python non ha un tipo scalare separato "char".

Sezioni di corde

La sintassi "sezione" è un modo pratico per fare riferimento alle parti secondarie delle sequenze, in genere stringhe ed elenchi. La sezione s[start:end] corrisponde agli elementi che iniziano all'inizio e si estendono fino alla fine, ma non includono. Supponiamo di avere s = "Ciao"

La stringa &quot;ciao&quot; con indici di lettere 0 1 2 3 4

  • s[1:4] è 'ell' -- caratteri che iniziano dall'indice 1 e si estendono fino all'indice 4 escluso
  • s[1:] è "ello": omettendo il valore predefinito dell'indice all'inizio o alla fine della stringa
  • s[:] è "Ciao": omettendo entrambi, si ottiene sempre una copia dell'intero elemento (questo è il modo pittonico per copiare una sequenza come una stringa o un elenco)
  • s[1:100] è "ello" -- un indice troppo grande viene troncato alla lunghezza della stringa

I numeri di indice in base zero standard consentono di accedere facilmente ai caratteri vicino all'inizio della stringa. In alternativa, Python usa numeri negativi per dare facile accesso ai caratteri alla fine della stringa: s[-1] è l'ultimo carattere 'o', s[-2] è 'l' il prossimo all'ultimo carattere, e così via. I numeri di indice negativi vengono conteggiati a partire dalla fine della stringa:

  • s[-1] è "o": ultimo carattere (il primo dalla fine)
  • s[-4] è "e": il quarto dalla fine
  • s[:-3] sta per "He" - aumentando ma non includendo gli ultimi 3 caratteri.
  • s[-3:] è 'llo': inizia con il terzo carattere dalla fine e si estende fino alla fine della stringa.

È un'ordinata verità di sezioni che per qualsiasi indice n, s[:n] + s[n:] == s. Funziona anche per n negativo o fuori dai limiti. In alternativa, utilizza un altro metodo s[:n] e s[n:] suddividono sempre la stringa in due parti di stringa, conservando tutti i caratteri. Come vedremo in seguito nella sezione Elenco, le sezioni funzionano anche con gli elenchi.

Formattazione delle stringhe

Python può convertire automaticamente gli oggetti in stringhe da stampare. Due modi integrati per farlo sono le stringhe letterali formattate, chiamate anche "f-strings", e la chiamata a str.format().

Valori letterali stringa formattati

Spesso vengono utilizzati valori letterali stringa formattati in situazioni quali:

  value = 2.791514
  print(f'approximate value = {value:.2f}')  # approximate value = 2.79

  car = {'tires':4, 'doors':2}
  print(f'car = {car}') # car = {'tires': 4, 'doors': 2}

Una stringa letterale formattata è preceduta da "f" (come il prefisso "r" utilizzato per le stringhe non elaborate). Il testo al di fuori delle parentesi graffe "{}" viene stampato direttamente. Le espressioni contenute in "{}" vengono stampate utilizzando la specifica del formato descritta nelle specifiche del formato.Puoi fare molte cose interessanti con la formattazione, tra cui il troncamento e la conversione in notazione scientifica e l'allineamento a sinistra/destra/centro.

Le stringhe f sono molto utili quando vuoi stampare una tabella di oggetti e vuoi che le colonne che rappresentano i diversi attributi degli oggetti siano allineate

  address_book = [{'name':'N.X.', 'addr':'15 Jones St', 'bonus': 70},
      {'name':'J.P.', 'addr':'1005 5th St', 'bonus': 400},
      {'name':'A.A.', 'addr':'200001 Bdwy', 'bonus': 5},]

  for person in address_book:
    print(f'{person["name"]:8} || {person["addr"]:20} || {person["bonus"]:>5}')

  # N.X.     || 15 Jones St          ||    70
  # J.P.     || 1005 5th St          ||   400
  # A.A.     || 200001 Bdwy          ||     5

% stringa

Python ha anche una vecchia funzionalità simile a printf() per creare una stringa. L'operatore % prende una stringa di formato di tipo printf a sinistra (%d int, stringa %s, virgola mobile %f/%g) e i valori corrispondenti in una tupla a destra (una tupla è costituita da valori separati da virgole, generalmente raggruppati tra parentesi):

  # % operator
  text = "%d little pigs come out, or I'll %s, and I'll %s, and I'll blow your %s down." % (3, 'huff', 'puff', 'house')

La riga riportata sopra è un po' lunga: supponi di volerla suddividere in righe separate. Non puoi semplicemente dividere la riga dopo "%" come faresti in altri linguaggi, poiché per impostazione predefinita Python tratta ogni riga come un'istruzione separata (il lato positivo è il motivo per cui non dobbiamo digitare il punto e virgola su ogni riga). Per risolvere questo problema, racchiudi l'intera espressione in un insieme di parentesi esterne. Successivamente, l'espressione potrà estendersi su più righe. Questa tecnica delle linee di codice funziona con i vari costrutti di raggruppamento descritti di seguito: ( ), [ ], { }.

  # Add parentheses to make the long line work:
  text = (
    "%d little pigs come out, or I'll %s, and I'll %s, and I'll blow your %s down."
    % (3, 'huff', 'puff', 'house'))

È meglio, ma la linea è ancora un po' lunga. Python ti consente di dividere le righe in blocchi, che verranno poi concatenati automaticamente. Quindi, per accorciare ulteriormente questa riga, possiamo:

  # Split the line into chunks, which are concatenated automatically by Python
  text = (
    "%d little pigs come out, "
    "or I'll %s, and I'll %s, "
    "and I'll blow your %s down."
    % (3, 'huff', 'puff', 'house'))

Stringhe (Unicode e byte)

Le stringhe Python normali sono Unicode.

Python supporta anche stringhe composte da byte semplici (indicati dal prefisso "b" davanti a un valore letterale stringa) come:

> byte_string = b'A byte string'
> byte_string
  b'A byte string'

Una stringa Unicode è un tipo di oggetto diverso da una stringa di byte, ma varie librerie, come le espressioni regolari, funzionano correttamente se vengono trasmesse entrambi i tipi di stringa.

Per convertire una stringa Python normale in byte, chiama il metodo encode() sulla stringa. Andando nell'altra direzione, il metodo decode() della stringa di byte converte i byte normali codificati in una stringa Unicode:

> ustring = 'A unicode \u018e string \xf1'
> b = ustring.encode('utf-8')
> b
b'A unicode \xc6\x8e string \xc3\xb1'  ## bytes of utf-8 encoding. Note the b-prefix.
> t = b.decode('utf-8')                ## Convert bytes back to a unicode string
> t == ustring                         ## It's the same as the original, yay!

True

Nella sezione relativa alla lettura del file, puoi trovare un esempio che mostra come aprire un file di testo con un certo livello di codifica e leggere le stringhe Unicode.

Istruzione If

Python non usa { } per racchiudere blocchi di codice per if/loops/function ecc. Per raggruppare le istruzioni, Python utilizza invece i due punti (:) e il rientro/spazio vuoto. Il test booleano per indicare se non è necessario essere tra parentesi (grande differenza da C++/Java) e può avere clausole *elif* e *else* (la parola "elif" ha la stessa lunghezza della parola "else").

È possibile utilizzare qualsiasi valore come test if. Tutti i valori "zero" vengono conteggiati come false: Nessuno, 0, stringa vuota, elenco vuoto, dizionario vuoto. Esiste anche un tipo booleano con due valori: True e False (convertiti in int, questi sono 1 e 0). Python ha le solite operazioni di confronto: ==, !=, <, <=, >, >=. A differenza di Java e C, == è sovraccarico per funzionare correttamente con le stringhe. Gli operatori booleani sono le parole scritte *and*, *or*, *not* (Python non usa lo stile C && || !). Ecco come potrebbe apparire il codice per un'app per la salute che fornisce consigli su bevande durante la giornata: nota come ogni blocco di istruzioni allora/else inizia con : e le istruzioni sono raggruppate in base al rientro:

  if time_hour >= 0 and time_hour <= 24:
    print('Suggesting a drink option...')
    if mood == 'sleepy' and time_hour < 10:
      print('coffee')
    elif mood == 'thirsty' or time_hour < 2:
      print('lemonade')
    else:
      print('water')

Trovo che omettere ":" sia l'errore di sintassi più comune quando digito nel tipo di codice precedente, probabilmente perché è un'altra cosa da digitare rispetto alle mie abitudini C++/Java. Inoltre, non inserire il test booleano tra parentesi: questa è un'abitudine di C/Java. Se il codice è breve, puoi inserirlo nella stessa riga dopo ":", in questo modo (questo vale anche per funzioni, loop e così via), anche se alcune persone ritengono che sia più leggibile spaziare i dati su righe separate.

  if time_hour < 10: print('coffee')
  else: print('water')

Esercizio: string1.py

Per esercitarti con il materiale di questa sezione, prova l'esercizio string1.py in Esercizi di base.