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. P>
Example String: < / p> 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. p> p> '\ n'.join (string_variable [-1] .split (' \ n ') [1: -1 ]) code> 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. p>
4 Réponses :
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
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. P>
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. P>
La fonction suivante doit vous donner la sortie souhaitée: p> Vous ne pouvez pas le tester avec: p> génère le sortie: p> 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. P> P>
Considérez une chaîne S qui ressemble à ceci:
'line2\nline3\nline4'
Une autre méthode consiste à diviser les données sur les nouvelles lignes, puis à rejoindre tout sauf la première et dernière ligne: ceci fonctionne bien sans données: p>
Comme indiqué par l'OP, cela sera très lent sur de grandes données.
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 () code> 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?