Domanda: sto usando split ('\ n') per ottenere linee in una stringa e ho scoperto che '' .split () restituisce un elenco vuoto [], mentre '' .split ('\ n') restituisce [''] .
Il metodo str.split () ha due algoritmi. Se non viene fornito alcun argomento, si divide su ripetute esecuzioni di spazi bianchi. Tuttavia, se viene fornito un argomento, viene trattato come un unico delimitatore senza ripetizioni.
Nel caso di dividere una stringa vuota, la prima modalità (nessun argomento) restituirà un elenco vuoto perché lo spazio bianco viene mangiato e non ci sono valori da inserire nell'elenco dei risultati.
Al contrario, la seconda modalità (con un argomento come \n
) produrrà il primo campo vuoto. Considera se avessi scritto '\n'.split('\n')
, otterrai due campi (uno diviso, ti dà due metà).
Domanda: c'è qualche motivo specifico per tale differenza?
Questa prima modalità è utile quando i dati sono allineati in colonne con quantità variabili di spazi bianchi. Per esempio:
>>> data = '''\
Shasta California 14,200
McKinley Alaska 20,300
Fuji Japan 12,400
'''
>>> for line in data.splitlines():
print line.split()
['Shasta', 'California', '14,200']
['McKinley', 'Alaska', '20,300']
['Fuji', 'Japan', '12,400']
La seconda modalità è utile per i dati delimitati come CSV in cui le virgole ripetute indicano campi vuoti. Per esempio:
>>> data = '''\
Guido,BDFL,,Amsterdam
Barry,FLUFL,,USA
Tim,,,USA
'''
>>> for line in data.splitlines():
print line.split(',')
['Guido', 'BDFL', '', 'Amsterdam']
['Barry', 'FLUFL', '', 'USA']
['Tim', '', '', 'USA']
Nota, il numero di campi risultato è uno maggiore del numero di delimitatori. Pensa di tagliare una corda. Se non fai tagli, hai un pezzo solo. Fare un taglio, dà due pezzi. Fare due tagli, dà tre pezzi. E così è con il metodo str.split (delimitatore) di Python :
>>> ''.split(',') # No cuts
['']
>>> ','.split(',') # One cut
['', '']
>>> ',,'.split(',') # Two cuts
['', '', '']
Domanda: esiste un modo più conveniente per contare le linee in una stringa?
Sì, ci sono un paio di modi semplici. Uno usa str.count () e l'altro usa str.splitlines () . Entrambi i modi daranno la stessa risposta a meno che non manchi la riga finale \n
. Se manca la riga finale, l' approccio str.splitlines fornirà la risposta esatta. Una tecnica più veloce che è anche accurata utilizza il metodo di conteggio ma poi lo corregge per la nuova riga finale:
>>> data = '''\
Line 1
Line 2
Line 3
Line 4'''
>>> data.count('\n') # Inaccurate
3
>>> len(data.splitlines()) # Accurate, but slow
4
>>> data.count('\n') + (not data.endswith('\n')) # Accurate and fast
4
Domanda di @Kaz: perché diamine ci sono due algoritmi molto diversi messi insieme in un'unica funzione?
La firma per str.split ha circa 20 anni e un certo numero di API di quell'epoca sono strettamente pragmatiche. Anche se non perfetto, la firma del metodo non è nemmeno "terribile". Per la maggior parte, le scelte di progettazione API di Guido hanno superato la prova del tempo.
L'API corrente non è priva di vantaggi. Considera stringhe come:
ps_aux_header = "USER PID %CPU %MEM VSZ"
patient_header = "name,age,height,weight"
Quando viene chiesto di suddividere queste stringhe in campi, le persone tendono a descrivere entrambe usando la stessa parola inglese "split". Quando viene chiesto di leggere codice come fields = line.split()
o fields = line.split(',')
, le persone tendono a interpretare correttamente le istruzioni come "divide una riga in campi".
Lo strumento di testo in colonne di Microsoft Excel ha fatto una scelta API simile e incorpora entrambi gli algoritmi di divisione nello stesso strumento. Le persone sembrano modellare mentalmente la divisione dei campi come un singolo concetto anche se è coinvolto più di un algoritmo.