Найти - Пользователи
Полная версия: текст А и В, если строчка из текста В есть в А - удалить ее
Начало » Python для новичков » текст А и В, если строчка из текста В есть в А - удалить ее
1 2 3 4
superduck
def uniqar(arr):
arr2 = []
for v in arr:
arr2.append(v.strip())
return list(set(arr2))


text = uniqar(open('text.txt', 'r').readlines())
text2 = uniqar(open('text2.txt', 'r').readlines())

text_tmp = text[:]
z = 0

for i in text_tmp:
print str(z) + '/' + str(len(text))
z += 1

if i in text2:
text.remove(i)
del(text_tmp)

ff = open('new_text.txt','w')
ff.write("\n".join(text))
ff.close()
этот код работает крайне медленно.. с текстами от 100к строчек просто жутко медленно.
как можно сделать быстрее?
expee
Если текст очень большой, то он и будет работать медленно. Можешь расставить принты после некоторых операций и посмотреть, какие блоки сколько выполняются. Кстати, а чем text.replace('string', '') не устроил? Разбить текст на слова можно методом split:
text = open('text.txt').read()
print text.split()
Получишь список слов.
expee
Вообще можно написать как-то так:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

words = open('haha').read()
intxt = open('huhu').read()

for word in words.split('/n'):
intxt = intxt.replace(word, '')

with open('new', 'w') as n:
n.write(intxt)
superduck
expee, твой метод работает гораздо медленнее моего метода с массивами.
PooH
Если я правильно понял задачу: “Отфильтровать из файла А все строки из файла В. Сравнение должно не учитывать пробельные элементы”, то наверное так:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

def normalize(s):
return ''.join(x.strip() for x in s.split())

dt = dict((normalize(x),True) for x in open('1.txt'))
outf = open('3.txt', 'w')
for s in open('2.txt'):
if not normalize(s) in dt:
outf.write(s)
expee
От твоего исходного файла с текстом на выходе функции uniqar остаются лишь уникальные строки. Т.о. у меня есть текст, где встречаются одинаковые строки (например, команды в листингах, но их нет в файле B!) и после обработки на выходе не хватает строк =/ В заголовке ты написал, что нужно удалять только строки, которые етсь в файле B.

Берем файл text, в котором 100к строк. Я для примера взял чередующиеся строки. В файле lines только одна строка, которая встречается в text (поскольку строк 100к и они чередуются, то таких строк в text 50к). После выполнения твоего кода у меня остается лишь одна строка - которых было в text 50к и при этом небыло в lines! Допустим, что это ошибка. Не будем обрабатывать функцией uniqar исходный текст. Вот результат выполнения твоего кода:
real 1m15.745s
user 1m4.240s
sys 0m1.872s
Сразу сознаюсь, что я сначала не понял тебя и написал код для удаления слов из текста B в тексте A. Но я исправился :)
#!/usr/bin/env python
# -*- coding: utf-8 -*-

lines = open('lines').readlines() # файл, из которого нужно брать строки и удалять в intxt
intxt = open('text').read() # файл, из которого нужно удалять строки, которые есть в lines

for line in lines:
intxt = intxt.replace(line, '')

with open('new', 'w') as n:
n.write(intxt.replace('\n\n', '\n'))
Скрипт удаляет все строки, какие есть в lines из text. Выполняем:
expee@localhost:~/dev/python$ time python hehe.py

real 0m0.087s
user 0m0.068s
sys 0m0.008s
Резальтат получаем правильный - в файле 50к строк и нет строк, которые есть в lines.
Ed
Вот мой вариант. На моих данных (2 одинаковых файла с уникальными строками) он работает быстрее исходного и варианта expee. Намного.
Но я допускаю, что на других данных он может быть медленнее.

Кстати, вариант expee у меня работает непозволительно долго. Входной файл в моем случае - это 190K строк длиной около 60 символов.
По-моему replace - не лучшее решение для таких длинных строк.

def uniqar(arr):
return set([v.strip() for v in set(arr)])

text = uniqar(open('text.txt', 'r').readlines())
text2 = uniqar(open('text2.txt', 'r').readlines())

ff = open('new_text.txt','w')
ff.write("\n".join(text.difference(text2)))
ff.close()
PS: Этот вариант сделан на основе кода топикстартера, поэтому он тоже удаляет одинаковые строки.
Я ориентировался на код, а не на слова :)
Ed
И еще. Непонятно, что значит ‘жутко медленно’. Потому как у меня такая статистика для моих данных:
Исходный вариант: 4.7 сек (не сказал бы, что это жутко медленно)
Вариант expee: ждал минут 5, не дождался окончания
Мой вариант: 0.4 сек

Подозреваю, что это еще и от ОС зависит и от мощности компа. У меня линух. комп - P4 2.8 GHz
superduck
2 Ed
спс, твой вариант работает быстрее вдух остальных предложеных и да, код expee работает очень медленно, не знаю откуда у него такие цифры о времени

450к строк, средняя длина 30символов
код Ed'a
real 0m1.784s
user 0m1.536s
sys 0m0.196s

код PooH'a
real 0m4.558s
user 0m4.312s
sys 0m0.124s


И еще. Непонятно, что значит ‘жутко медленно’.
поставил на его скрипе счётчик в цикле, была скорость около 20строк/сек. т.е даже рядом по скорости не стоит с моим первоночальным кодом..
expee
Даже не знаю, как вы считаете :) Взял сейчас файл ~180000 строк по 150 символов. Каждая 3 строка подлежит удалению (есть в lines). Общее количество символов - 27 333 305. Запускаем мой скрипт:
expee@localhost:~/dev/python$ time python hehe.py

real 0m2.232s
user 0m0.164s
sys 0m0.164s
Получаем файл с ~60к строками. Нужна строка удалена.

ps. проц - amd duron 1200.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB