12
votes

Le moyen le plus rapide de supprimer les premières lignes d'une chaîne Python

J'ai un script Python qui, pour diverses raisons, a une variable une chaîne assez grande, disons 10 Mo de long. Cette chaîne contient plusieurs lignes.

Quel est le moyen le plus rapide de supprimer les premières et les dernières lignes de cette chaîne? En raison de la taille de la chaîne, plus l'opération est rapide, meilleure; Il y a une emphase à la vitesse. Le programme renvoie une chaîne légèrement plus petite, sans les premières lignes.

'\ n'.join (string_variable [-1] .split (' \ n ') [1: -1 ]) est le moyen le plus simple de le faire, mais il est extrêmement lent, car la fonction Split () copie l'objet en mémoire, et la jointure () la copie à nouveau.

Example String: < / p> xxx

crédit supplémentaire: avoir ce programme ne pas étrangler s'il n'y a pas de données entre les deux; Ceci est facultatif, car, pour mon cas, il ne devrait pas y avoir de chaîne sans données entre les deux.


1 commentaires

Avez-vous un contrôle sur la manière dont la chaîne entre dans votre programme, par exemple: faites-vous my_string = file_obj.read () pour récupérer la chaîne? En outre, avez-vous besoin de toutes les lignes présentes en mémoire à la fois, ou est une seule ligne à la fois, d'accord?


4 Réponses :


12
votes

première scission à '\ n' code> une fois, puis vérifiez si la chaîne de la dernière index contient '\ n' code>, si oui str.rsplit Code> à '\ n' code> une fois et choisissez l'élément à 0th index, renvoyez une chaîne vide:

>>> def solve_fast(s):
    ind1 = s.find('\n')
    ind2 = s.rfind('\n')
    return s[ind1+1:ind2]
... 
>>> s = '''*** START OF DATA ***
data
data
data
*** END OF DATA ***'''
>>> solve_fast(s)
'data\ndata\ndata'
>>> s = '''*** START OF DATA ***
*** END OF DATA ***'''
>>> solve_fast(s)
''
>>> s = '\n'.join(['a'*100]*10**5)
>>> %timeit solve_fast(s)
100 loops, best of 3: 2.65 ms per loop


0 commentaires

0
votes

Selon la manière dont votre étui d'utilisation consommera la chaîne, le moyen plus rapide de l'éliminer peut ne pas le retirer.

Si vous envisagez d'accéder aux lignes de la chaîne, vous pouvez créer un générateur qui saute la première et la dernière ligne tout en cédant chaque ligne comme étant consommée plutôt que de construire un nouvel ensemble de copies de toutes les lignes totalement.

Un moyen ad hoc pour éviter la première et la dernière ligne est d'itérer sur La chaîne sans générer des copies inutiles est en gardant une trace de trois lignes suivantes et ne renvoyant que le 2e one, de cette façon, l'itération se terminera avant d'atteindre la dernière ligne sans qu'il soit nécessaire de connaître la position de la dernière pause de la ligne.

La fonction suivante doit vous donner la sortie souhaitée: xxx

Vous ne pouvez pas le tester avec: xxx

génère le sortie: xxx

Notez que le plus grand avantage de cette approche est que ne créera qu'une nouvelle ligne à l'époque et ne prendra pratiquement pas de temps à GE Nère la première ligne de sortie (plutôt que d'attendre que toutes les lignes soient trouvées avant de poursuivre davantage) mais, encore une fois, cela peut être utile ou non en fonction de votre cas d'utilisation.


0 commentaires

10
votes

Considérez une chaîne S qui ressemble à ceci:

'line2\nline3\nline4'


0 commentaires

0
votes

Une autre méthode consiste à diviser les données sur les nouvelles lignes, puis à rejoindre tout sauf la première et dernière ligne: xxx

ceci fonctionne bien sans données: xxx < / pré>


1 commentaires

Comme indiqué par l'OP, cela sera très lent sur de grandes données.