Python удалить пустые строки из файла
Автор оригинала: Peter Rubio.
Когда мысленно приближаются к этой проблеме, вы можете соблазнены использовать «для цикла». Я признаю, что это то, как мой разум работал: итерация через список один элемент за один раз и проверьте пустые строки. Если он пуст, удалите его. Повторить.
Метод 1: для цикла
Что произойдет, если мы используем для цикла?
При принятии решения о том, какой цикл использовать, мой инстинкт пошел прямо к «для петли». Это связано с тем, что мы хотим повторить проверку пустой строки для каждого элемента во всей длине списка, который можно легко определить следующим образом:
Так что на самом деле здесь происходит? Оказывается, это не хорошая идея, чтобы удалить элементы из списка в «для петли», потому что индексы изменится!
Осмотрите вышеуказанный список, мы видим, что нам нужно удалить индексы 1, 3, 5 и 7. Мы сможем имитировать наши «за петлю».
Первая итерация Я 0, слова [0] это " | Отказ Это не равно "" Отказ Список без изменений.
Третья итерация Я 2, слова [2] это "" Отказ Это равно "" Итак, мы его удаляем. Вот модифицированный список:
Четвертая итерация Я 3, слова [3] это "" Итак, мы его удаляем. Вот модифицированный список:
Пятая итерация Я 4, слова [4] это "" " Итак, мы его удаляем. Вот модифицированный список:
Мы уже видим, что мы удалили все пустые строки, однако, мы до сих пор не закончили итерацию по нашему определенному «для цикла», которые являются государствами, чтобы повторить длину списка слов, которые были изначально 8!
Вот еще одно изменение «для петли», где мы вместо этого используем способ удаления для удаления первого вхождения в списке.
Как видно выше код выполняется без Ошибка индекса Отказ После завершения «для цикла» и печати результатов, мы можем увидеть слова Список все еще содержит две пустые строки.
Давайте пройдем каждую итерацию. Выделение будет представлять текущий итератор.
1-я итерация Я это " | , это не равно "" Отказ Список без изменений, авансы итераторы.
2 итерация Я это "" Отказ
Это равно "" Итак, мы называем функцию удаления. Обратите внимание, что следующая пустая строка находится на текущей версии итератора.
Однако итератор должен продвинуться к следующему элементу.
3 итерация Я это "Быстрый" , это не равно "" Отказ Список без изменений, авансы итераторы.
4 итерация Я это "" Отказ Это равно "" Итак, мы называем функцию удаления. Обратите внимание, что пустая строка в индексе 1 удаляется. Это сдвигает следующую пустую строку к текущей версии итерации.
5-я итерация Я это "Браун" , Это не равно "" Отказ Список без изменений, авансы итераторы.
6 итерация Я это "" Итак, мы называем функцию удаления. Обратите внимание, что пустая строка в индексе 2 удаляется и заставляет текущий итератор быть "Фокс" Отказ
Поскольку итератор сейчас находится в конце списка, это будет последнее сравнение.
Это равно "" Итак, мы называем функцию удаления. Примечание. Пустая строка при индексе 2 удаляется.
Прежде чем мы обсудим однонаторные решения, вот умный способ решить его, используя 2 строки с помощью «While Loop».
Как написано выше, ключевое слово Python «In» используется для условия: до тех пор, пока есть пустая строка в списке слов, мы вызовем функцию удаления в списке. Как указано ранее, функция удаления удалит первое вхождение в списке.
Некоторые элегантные альтернативы
У вас есть PEEK на этих альтернативных решениях и посмотрим, сможете найти способы вписать их в свой код. О, и если вы считаете себя опытным питонистом и стремились основывать свою кодирующую жизнь на Дзен Питона Тогда эти решения подойдут вам. Как вы скоро увидите, что эти методы отлично выровняются с философией Python. Если вы еще не знакомы с Дзен Питона Tim Peters, то я приглашаю вас
Метод 2: Функция фильтра ()
Встроенный Python Фильтр Функция использует следующий формат: Фильтр (функция, утечка) Отказ
Примечание: согласно Python Docs Функция фильтра «строит итератор». Давайте рассмотрим результат, чтобы увидеть, что это значит.
Приведенное выше показано, что содержимое отфильтрованного списка на самом деле не печатается, и мы остались с объектом фильтра. Для того, чтобы на самом деле увидеть результаты, нам нужно преобразовать его в объект списка.
И если вышеуказанное выражение лямбда не было чем-то, что вы инстинктивно думали или не так элегантны, как вы хотели бы, то, возможно, эти другие решения пополняют ваш переулок.
Как насчет определения лямбда проверить на наличие строк, которые имеют длину?
Пока строка имеет длину, она останется в списке. В противном случае это считается пустой строкой и отфильтровывается.
Способ 3: Понимание списка
Другой Python One-liLer, который я приглашаю, чтобы исследовать это Список понимания . От Python Docs. : «Понимание списка состоит из скобок, содержащих выражение, сопровождаемое предложение для предложения, то ноль или более для или если положения« » Отказ
Применим это в наш список строк и проверьте понимание списка, которое я определен ниже.
Я проиграет через слова список. Пока это не пустая строка, то он будет добавлен в новый список, называемый new_words Отказ Мы просто назначаем понимание списка в переменной.
Вот полный фрагмент кода.
Альтернатива для приведенного выше заявления о том, чтобы проверить что Я имеет длину.
И вот как мы удаляем пустые строки со списком пониманием.
Резюме
Кроме того, я надеюсь, что вы сейчас полностью осознаете, что происходит при использовании «для цикла» для удаления элементов в списке. Как объяснено выше, вам может побазвать и получить индексную ошибку. Но будьте осторожны с другими ситуациями, когда вы не получаете ошибку, и ваш код все еще выполняется. В нашем примере «За LOOP» завершено и оставили две пустые строки в списке!
Наконец, я хотел бы побудить вас читать через Дзен Питона Если вы еще этого не сделали. Пусть он будет служить дополнительным вдохновением для кодирования Python Way. И прежде чем узнать это, вы скоро узнаете, что создаете красивый код.
допустим, у меня есть текстовый файл, полный псевдонимов, как я могу удалить конкретный псевдоним из этого файла?
предполагая, что ваш файл имеет формат одного псевдонима на строку, используйте это.
Сначала откройте файл:
далее, Получить все строки из файла:
теперь вы можете закрыть файл:
и снова открыть его в режиме записи:
затем напишите свои строки обратно, кроме строки, которую вы хотите удалить. Возможно, вы захотите изменить "\n" к любой строке, заканчивающейся вашим файлом.
At конец, закройте файл снова.
решение этой проблемы только один:
Это решение открывает файл в режиме r / w ("r+") и использует seek для сброса F-указателя, а затем усекает, чтобы удалить все после последней записи.
лучший и самый быстрый вариант, вместо того, чтобы хранить все в списке и повторно открывать файл для его записи, по-моему, переписать файл в другом месте.
вот именно! В одном цикле, и только вы можете сделать то же самое. Это будет намного быстрее.
это "вилка" от @Lotherответ (который я считаю, что следует считать правильным ответом).
Для такого файла:
эта вилка из решения Lother отлично работает:
- with open , которые отбрасывают использование f.close()
- более яснее if/else для оценки, если строка отсутствует в текущей строке
проблема с чтением строк в первом проходе и внесением изменений (удаление определенных строк) во втором проходе заключается в том, что если размеры файлов огромны, у вас закончится ОЗУ. Вместо этого лучше читать строки одну за другой и записывать их в отдельный файл, исключая те, которые вам не нужны. Я запустил этот подход с файлами размером 12-50 ГБ, и использование ОЗУ остается почти постоянным. Только циклы CPU показывают, что обработка продолжается.
если вы используете Linux, вы можете попробовать следующий подход.
Предположим, у вас есть текстовый файл с именем animal.txt :
удалить первую строку:
Я думаю, если Вы читаете файл в список, то вы можете перебирать список, чтобы найти псевдоним, от которого хотите избавиться. Вы можете сделать это очень эффективно, не создавая дополнительных файлов, но вам придется записать результат обратно в исходный файл.
вот как я мог бы это сделать:
Я предполагаю, что nicknames.csv содержит такие данные, как:
затем загрузите файл в список:
далее, повторите список чтобы соответствовать вашим входам для удаления:
наконец, записать результат обратно в файл:
не очень хорошо решить, если вы поместите весь файл в память, я знаю, что в настоящее время у всех есть тонны памяти, но подумайте, если файл несколько ГБ журналов или что-то еще.
лучший способ скопировать его строка за строкой в новый файл, чем удалить первый или что-то вроде этого
В общем, вы не можете; вы должны написать весь файл снова (по крайней мере, с момента изменения до конца).
в некоторых случаях вы можете сделать лучше, чем это -
Если все ваши элементы данных одинаковой длины и в определенном порядке, и вы знаете смещение того, от которого вы хотите избавиться, вы можете скопировать последний элемент поверх того, который будет удален, и усечь файл перед последним элементом;
или вы можете просто перезаписать фрагмент данных с помощью значения "это плохие данные, пропустите его" или сохраните флаг "этот элемент был удален"в сохраненных элементах данных, чтобы вы могли пометить его удаленным без изменения файла.
Это, вероятно, перебор для коротких документов (что-нибудь под 100 КБ?).
Мне понравился подход fileinput, как описано в этот ответ: удаление строки из текстового файла (python)
скажем, например, у меня есть файл, в котором есть пустые строки, и я хочу удалить пустые строки, Вот как я его решил:
Примечание: пустые строки в моем случае имели длину 1
Наверное, вы уже получили правильный ответ,но вот мой. Вместо того, чтобы использовать список для сбора нефильтрованных данных (что readlines() метод), я использую два файла. Один предназначен для хранения основных данных, а второй-для фильтрации данных при удалении определенной строки. Вот код:
надеюсь, вы найдете это полезным! :)
сохраните строки файла в списке, затем удалите из списка строку, которую вы хотите удалить, и запишите оставшиеся строки в новый файл
возьмите содержимое файла, разделите его по новой строке на кортеж. Затем получите доступ к номеру строки кортежа, присоединитесь к кортежу результата и перезапишите файл.
Есть некий файл, состоящий из строк. Нужно удалить выборочно строки, начинающиеся с определенного набора символов при помощи python. Как это сделать?
нужно удалить все, что начинается с ANISOU
Как удалить каждую вторую строку из файла на python?
Используя fileinput , чтобы прозрачно создать временный файл, чтобы по месту изменения выполнить:
Этот for-цикл можно также записать, используя itertools.islice :
Если реализация .writelines() не пишет строки по мере поступления, а загружает их всех в память, то можно использовать явный for-цикл, чтобы по одной строке писать, не загружая весь файл в память.
Для небольшого файла полный код может использовать .readlines() , чтобы получить список строк (загрузить файл в память) и целиком перезаписать этот файл, рискуя потерять данные если ошибка возникнет:
Для небольшого файла, заданного с командной строки или стандартного ввода (stdin), пренебрегая возможными ошибками, можно кратко записать:
это полный скрипт. Использование:
В более общем случае, чтобы удалить строки по месту из файла, не создавая временный файл и не загружая всё содержимое в память, seek()/tell() работают, но вероятно менее эффективное решение создают:
Этот более сложный вариант работает и для файлов, которые как в оперативную память не помещаются так и для которых нет места, чтобы копию на диске создать.
нужно удалить все, что начинается с ANISOU
Можно адаптировать приведённые выше примеры кода:
Можно самостоятельно временный файл создать (к примеру, если в текущей директории не достаточно места для копии файла, можно явно другую директорию указать (на другом диске) и использовать shutil.move() , если необходимо):
Загрузив строки в память:
Легко адаптировать к другим условиям, определив keep_line() предикат, к примеру:
Краткий ответ: Вы можете удалить все пустые списки из списка списков, используя оператор понимания списка [X для X в списке, если x] Чтобы отфильтровать список.
Далее вы узнаете о двух методах, использующих понимание списка и функцию фильтра () для удаления всех пустых списков из списка списков.
Но до этого не стесняйтесь играть с кодом самостоятельно:
Метод 1: Понимание списка
Как вы можете удалить все пустые списки из списка списков? Скажи, у вас есть список списков
И вы хотите, чтобы все пустые списки удалены, чтобы получить список списков
[[1, 2, 3], [1, 2], [1, 2, 3, 4]] .
Решение : Используйте Понимание списка [X для X в списке, если x] Чтобы отфильтровать список и удалить все списки, которые пусты.
Условие, если х оценивает Ложь только если список х пусто. Во всех остальных случаях он оценивает Правда И элемент включен в новый список.
Вы можете визуализировать поток выполнения здесь, нажав кнопку «Далее»:
Метод 2: Фильтр ()
Функция Filter () принимает два аргумента:
- Функция решения фильтра Чтобы проверить каждый элемент, следует ли включить его в отфильтрованную передачу (он возвращает логическое значение), а также
- ИТЕРИТЕЛЬНО быть отфильтрованным.
Как функция решения фильтра, вы используете функцию идентификации, которая просто передает список. Почему эта работа? Потому что только пустой список будет оцениваться в Ложь Отказ Все остальные списки будут оцениваться до Правда (И, таким образом, передайте тест фильтрации).
- Как отфильтровать список в Python?
- Фильтр VS Список понимания (скорость)
- Список понимания
- Списки списков
Куда пойти отсюда?
Достаточно теории, давайте познакомимся!
Чтобы стать успешным в кодировке, вам нужно выйти туда и решать реальные проблемы для реальных людей. Вот как вы можете легко стать шестифункциональным тренером. И вот как вы польские навыки, которые вам действительно нужны на практике. В конце концов, что такое использование теории обучения, что никто никогда не нуждается?
Вы хотите стать мастером кода, сосредоточившись на практических кодовых проектах, которые фактически зарабатывают вам деньги и решают проблемы для людей?
Работая в качестве исследователя в распределенных системах, доктор Кристиан Майер нашел свою любовь к учению студентов компьютерных наук.
Его страсти пишут, чтение и кодирование. Но его величайшая страсть состоит в том, чтобы служить стремлению кодер через Finxter и помогать им повысить свои навыки. Вы можете присоединиться к его бесплатной академии электронной почты здесь.
Читайте также: