#python
Вопрос:
Я могу извлечь вывод с помощью простого файла небольшого размера, но когда я использую большой файл, я получаю ошибку памяти
Большой РАЗМЕР файла до 4 ГБ
Вот код
with open('file2.txt', 'r') as k:
keywords = k.read().splitlines()
#2
with open('file1.txt') as f, open('output.txt', 'w') as o:
for line in f:
if any(key in line for key in keywords):
o.writelines(line)
Ошибка
Traceback (most recent call last):
File "C:crackmatch.py", line 2, in <module>
keywords = k.read().splitlines()
MemoryError
Комментарии:
1. Какой файл является большим файлом?
2. @Barmarв сообщении об ошибке говорится, что это файл ключевых слов.
3. Насколько велика память вашего компьютера? Рассматривали ли вы возможность его обновления или освобождения места, чтобы эта программа могла работать? Возможно, вы могли бы добавить файл подкачки или файл подкачки, хотя это может быть медленным.
4. Что вы делаете, если у вас 4 ГБ ключевых слов? Это похоже на большее количество слов, чем есть в языке.
5.
/usr/share/dict/words
составляет всего 2 МБ
Ответ №1:
Похоже, вам нужна эффективная структура данных с памятью для хранения ключевых слов, а затем проверки того, существуют ли они в file2.txt или нет. Я предлагаю использовать структуру данных Trie, чтобы ваша память не заканчивалась.
Кроме того, избегайте чтения всего файла сразу, читайте содержимое файла ключевых слов по одной строке за раз и вставляйте его в trie.
Быстрый рефакторинг вашего кода может выглядеть следующим образом:
from colletions import defaultdict
class Node:
def __init__(self):
self.children = defaultdict(Node)
self.end = False
class Trie:
def __init__(self):
self.root = Node()
def insert(self, word: str) -> None:
cur = self.root
for c in word:
cur = cur.children[c]
cur.end = True
def contains(self, word: str) -> bool:
cur = self.root
for c in word:
if c not in cur.children: return False
cur = cur.children[c]
return cur.end
# changes to your code below:
keywords = Trie()
with open('file2.txt', 'r') as k:
for keyword in k:
keywords.insert(keyword)
#2
with open('file1.txt') as f, open('output.txt', 'w') as o:
for line in f:
if keywords.contains(line):
o.writelines(line)
Примечание: Возможный недостаток использования Trie здесь заключается в том, что, если ключевые слова уникальны, может быть очень меньше перекрытий, и память, используемая trie, все равно может быть большой. Но все равно он должен быть значительно меньше 4 ГБ.
Комментарии:
1. Ваш тест-это неправильный путь. ОП хочет знать, какие строки содержат какие-либо ключевые слова, а не какие строки содержатся в ключевых словах. Вам нужно разделить каждую строку на набор слов, а затем проверить каждое из них. Возможно, было бы более эффективно также использовать набор ключевых слов, поскольку это позволило бы проверить все слова строки за одну операцию
if not keywords.isdisjoint(line.split()): o.write(line)
, т. Е. (ПРИМЕЧАНИЕ: не используйте линии записи, так как для этого требуется список строк).2. @Manparvesh Я получаю недопустимый файл синтаксической ошибки «match.py», строка 13, вставка def(self, word: str) -> Нет: ^ Ошибка синтаксиса: недопустимый синтаксис