Question: J'utilise split ('\ n') pour obtenir des lignes dans une chaîne, et j'ai trouvé que '' .split () renvoie une liste vide [], tandis que '' .split ('\ n') renvoie [''] .
La méthode str.split () a deux algorithmes. Si aucun argument n'est donné, il se divise sur des exécutions répétées d'espaces. Cependant, si un argument est donné, il est traité comme un délimiteur unique sans exécution répétée.
Dans le cas du fractionnement d'une chaîne vide, le premier mode (sans argument) renverra une liste vide car l'espace blanc est mangé et il n'y a aucune valeur à mettre dans la liste de résultats.
En revanche, le second mode (avec un argument tel que \n
) produira le premier champ vide. Considérez que si vous aviez écrit '\n'.split('\n')
, vous obtiendriez deux champs (une division, vous donne deux moitiés).
Question: Y a-t-il une raison spécifique à une telle différence?
Ce premier mode est utile lorsque les données sont alignées dans des colonnes avec des quantités variables d'espaces. Par exemple:
>>> 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']
Le deuxième mode est utile pour les données délimitées telles que CSV où des virgules répétées indiquent des champs vides. Par exemple:
>>> 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']
Notez que le nombre de champs de résultat est supérieur de un au nombre de délimiteurs. Pensez à couper une corde. Si vous ne faites aucune coupure, vous n'en avez qu'une seule pièce. Faire une coupe, donne deux morceaux. Faire deux coupes, donne trois morceaux. Et il en est de même avec la méthode str.split (délimiteur) de Python :
>>> ''.split(',') # No cuts
['']
>>> ','.split(',') # One cut
['', '']
>>> ',,'.split(',') # Two cuts
['', '', '']
Question: Et y a-t-il un moyen plus pratique de compter les lignes dans une chaîne?
Oui, il existe plusieurs moyens simples. L'un utilise str.count () et l'autre utilise str.splitlines () . Les deux méthodes donneront la même réponse à moins que la dernière ligne ne manque le \n
. Si la dernière nouvelle ligne est manquante, l' approche str.splitlines donnera la réponse exacte. Une technique plus rapide qui est également précise utilise la méthode de comptage, mais la corrige ensuite pour la nouvelle ligne 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
Question de @Kaz: Pourquoi diable y a-t-il deux algorithmes très différents en une seule fonction?
La signature de str.split a environ 20 ans, et un certain nombre d'API de cette époque sont strictement pragmatiques. Bien qu'elle ne soit pas parfaite, la signature de la méthode n'est pas non plus "terrible". Pour la plupart, les choix de conception d'API de Guido ont résisté à l'épreuve du temps.
L'API actuelle n'est pas sans avantages. Considérez des chaînes telles que:
ps_aux_header = "USER PID %CPU %MEM VSZ"
patient_header = "name,age,height,weight"
Lorsqu'on leur demande de diviser ces chaînes en champs, les gens ont tendance à décrire les deux en utilisant le même mot anglais, «split». Lorsqu'on leur demande de lire du code tel que fields = line.split()
ou fields = line.split(',')
, les gens ont tendance à interpréter correctement les déclarations comme "divise une ligne en champs".
L' outil de texte en colonnes de Microsoft Excel a fait un choix d'API similaire et intègre les deux algorithmes de fractionnement dans le même outil. Les gens semblent modéliser mentalement le fractionnement de champ comme un concept unique, même si plus d'un algorithme est impliqué.