W zależności od sposobu, w jaki twój przypadek użycia pochłonie ciąg, najszybszym sposobem jego usunięcia może być jego nie usunięcie.
Jeśli planujesz uzyskać dostęp do linii w łańcuchu sekwencyjnie, możesz zbudować generator, który pomija pierwszą i ostatnią linię, jednocześnie generując każdą linię, zamiast budować nowy zestaw kopii wszystkich linii.
Doraźnym sposobem uniknięcia pierwszej i ostatniej linii jest powtarzanie ciągu bez generowania niepotrzebnych kopii przez śledzenie trzech kolejnych linii i zwracanie tylko drugiej, w ten sposób iteracja zakończy się przed osiągnięciem ostatnia linia bez konieczności znajomości położenia ostatniej linii.
Poniższa funkcja powinna dać pożądany wynik:
def split_generator(s):
# Keep track of start/end positions for three lines
start_prev = end_prev = 0
start = end = 0
start_next = end_next = 0
nr_lines = 0
for idx, c in enumerate(s):
if c == '\n':
nr_lines += 1
start_prev = start
end_prev = end
start = start_next
end = end_next
start_next = end_next
end_next = idx
if nr_lines >= 3:
yield s[(start + 1) : end]
# Handle the case when input string does not finish on "\n"
if s[-1] != '\n' and nr_lines >= 2:
yield s[(start_next+1):end_next]
mogę przetestować go z:
print("1st example")
for filtered_strs in split_generator('first\nsecond\nthird'):
print(filtered_strs)
print("2nd example")
for filtered_strs in split_generator('first\nsecond\nthird\n'):
print(filtered_strs)
print("3rd example")
for filtered_strs in split_generator('first\nsecond\nthird\nfourth'):
print(filtered_strs)
print("4th example")
for filtered_strs in split_generator('first\nsecond\nthird\nfourth\n'):
print(filtered_strs)
print("5th example")
for filtered_strs in split_generator('first\nsecond\nthird\nfourth\nfifth'):
print(filtered_strs)
Will generuje dane wyjściowe:
1st example
second
2nd example
second
3rd example
second
third
4th example
second
third
5th example
second
third
fourth
pamiętać, że największa Zaletą tego podejścia jest to, że stworzy tylko jedną nową linię w czasie i praktycznie nie będzie czas na wygenerowanie pierwszego wiersza danych wyjściowych (zamiast oczekiwania na znalezienie wszystkich linii, zanim przejdziesz dalej), ale znowu, może być przydatny lub nie, w zależności od twojego przypadku użycia.
masz kontrolę nad tym, jak ciąg wchodzi do twojego programu, np .: czy robisz 'my_string = file_obj.read()', aby pobrać ciąg znaków? Czy potrzebujesz wszystkich linii obecnych w pamięci w tym samym czasie lub tylko jednej linii naraz? –