2.14. Concatenare liste e suddividere stringhe

Avete una lista di coppie chiave-valore nella forma chiave=valore e volete concatenarle in una singola stringa. Per concatenare qualunque lista di stringhe in una singola stringa, usate il metodo join di un oggetto stringa.

Esempio 2.35. Concatenare una lista in buildConnectionString

    return ";".join(["%s=%s" % (k, v) for k, v in params.items()])

Una nota interessante prima di continuare. Continuo a ripetere che le funzioni sono oggetti, le stringhe sono oggetti, qualunque cosa è un oggetto. Potreste aver pensato che intendessi dire che le variabili di tipo stringa sono oggetti. Ma no, guardando bene questo esempio vedrete che la stessa stringa ";" è un oggetto e state chiamando il suo metodo join.

Ad ogni modo, il metodo join concatena gli elementi della lista in una singola stringa, con ogni elemento separato da un punto e virgola. Il separatore non deve essere per forza un punto e virgola, non deve nemmeno essere per forza un singolo carattere. Può essere una stringa qualsiasi.

Importante
join funziona solamente su liste di stringhe, non applica alcuna forzatura sul tipo. Concatenare una lista che contiene uno o più oggetti che non sono di tipo stringa genererà un'eccezione.

Esempio 2.36. Output di odbchelper.py

>>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}
>>> ["%s=%s" % (k, v) for k, v in params.items()]
['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']
>>> ";".join(["%s=%s" % (k, v) for k, v in params.items()])
'server=mpilgrim;uid=sa;database=master;pwd=secret'

Questa stringa è quindi restituita dalla funzione help e stampata dal blocco chiamante, che vi restituisce quell'output che tanto vi ha meravigliato quando avete iniziato a leggere questo capitolo.

Nota storica.  Quando ho cominciato ad imparare Python, mi aspettavo che join fosse un metodo delle liste che potesse prendere come argomento il separatore. Molte persone la pensano in questo modo e c'è una storia dietro il metodo join. Prima di Python 1.6 le stringhe non avevano tutti questi utili metodi. C'era un modulo string separato che conteneva tutte le funzioni sulle stringhe; ogni funzione prendeva una stringa come primo parametro. Le funzioni erano sufficientemente importanti da essere inserite direttamente dentro gli oggetti di tipo stringa, cosa che aveva senso per funzioni come lower, upper, e split. Molti programmatori Python navigati obiettarono per la presenza del nuovo metodo join, sostenendo che doveva essere un metodo della classe lista, o che non dovesse essere spostato affatto e continuare ad appartenere al modulo string (che comunque continua ad avere un sacco di cose utili). Uso esclusivamente il nuovo metodo join, ma vedrete del codice scritto nell'altro modo e se la cosa vi dà davvero fastidio, potete continuare ad usare la vecchia funzione string.join.

Vi starete probabilmente chiedendo se c'è un metodo analogo per suddividere una stringa in una lista. E naturalmente c'è, è chiamato split.

Esempio 2.37. Suddividere una stringa

>>> li = ['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']
>>> s = ";".join(li)
>>> s
'server=mpilgrim;uid=sa;database=master;pwd=secret'
>>> s.split(";")    1
['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']
>>> s.split(";", 1) 2
['server=mpilgrim', 'uid=sa;database=master;pwd=secret']
1 split rovescia join suddividendo una stringa in una lista a molti elementi. Notate che il limitatore (“;”) viene completamente rimosso; non appare in nessuno degli elementi ritornati nella lista.
2 split prende un secondo argomento opzionale, che è il numero di volte in cui si vuole dividere la stringa. (“Oooooh, argomenti opzionali...” imparerete come utilizzarli nelle vostre funzioni nel prossimo capitolo.)
Nota
anystring.split (separatore, 1) è un'utile tecnica quando volete cercare in una stringa la presenza di una particolare sottostringa e quindi utilizzare tutto ciò che c'è prima di detta sottostringa (che va a finire nel primo elemento della lista ritornata) e tutto quello che c'è dopo (che va a finire nel secondo elemento).

Ulteriori letture