Ответ 1
Если вы хотите сохранить большой словарь, вы в основном смотрите на базу данных.
Python поставляется со встроенной поддержкой sqlite3, что дает вам легкое решение для базы данных, поддерживаемое файлом на диске.
У меня есть 400 миллионов строк уникальной информации о ключевом значении, которую я хотел бы получить для быстрого поиска в script. Мне интересно, что бы это было так. Я рассмотрел следующее, но не уверен, есть ли способ на диске отобразить словарь и не использовать много памяти, кроме как при создании словаря.
Пожалуйста, дайте мне знать, если что-то неясно.
Спасибо! -Abhi
Если вы хотите сохранить большой словарь, вы в основном смотрите на базу данных.
Python поставляется со встроенной поддержкой sqlite3, что дает вам легкое решение для базы данных, поддерживаемое файлом на диске.
В принципе модуль shelve делает именно то, что вы хотите. Он обеспечивает постоянный словарь, поддерживаемый файлом базы данных. Ключи должны быть строками, но полка будет заботиться о значениях травления/распиловки. Тип файла db может различаться, но он может быть хешем Berkeley DB, который является отличной базой для базы данных с легким весом.
Ваш размер данных звучит огромно, поэтому вы должны провести некоторое тестирование, но shelve/BDB, вероятно, зависит от него.
Примечание. Модуль bsddb устарел. Возможно, полка не будет поддерживать хеши BDB в будущем.
Никто не упомянул dbm. Он открывается как файл, ведет себя как словарь и находится в стандартном дистрибутиве.
Из документов http://docs.python.org/release/3.0.1/library/dbm.html
import dbm
# Open database, creating it if necessary.
db = dbm.open('cache', 'c')
# Record some values
db[b'hello'] = b'there'
db['www.python.org'] = 'Python Website'
db['www.cnn.com'] = 'Cable News Network'
# Note that the keys are considered bytes now.
assert db[b'www.python.org'] == b'Python Website'
# Notice how the value is now in bytes.
assert db['www.cnn.com'] == b'Cable News Network'
# Loop through contents. Other dictionary methods
# such as .keys(), .values() also work.
for k, v in db.iteritems():
print(k, '\t', v)
# Storing a non-string key or value will raise an exception (most
# likely a TypeError).
db['www.yahoo.com'] = 4
# Close when done.
db.close()
Я попробовал бы это перед любой из более экзотических форм, а использование shelve/pickle потянет все в память при загрузке.
Приветствия
Тим
Без сомнения (по-моему), если вы хотите, чтобы это продолжалось, Redis - отличный вариант.
import redis
ds = redis.Redis(host="localhost", port=6379)
with open("your_text_file.txt") as fh:
for line in fh:
line = line.strip()
k, _, v = line.partition("=")
ds.set(k, v)
Выше принимает файлы с такими значениями, как:
key1=value1
key2=value2
etc=etc
Измените вставку script в соответствии с вашими потребностями.
import redis
ds = redis.Redis(host="localhost", port=6379)
# Do your code that needs to do look ups of keys:
for mykey in special_key_list:
val = ds.get(mykey)
Почему мне нравится Redis.
Я не думаю, что вы должны попробовать маринованный дикт. Я уверен, что Python будет каждый раз обрабатывать все это, что означает, что ваша программа будет ждать ввода-вывода дольше, чем это возможно.
Это та проблема, для которой были изобретены базы данных. Вы думаете "NoSQL", но SQL-база данных тоже будет работать. Вы должны использовать SQLite для этого; Я никогда не делал базу данных SQLite большой, но в соответствии с этим обсуждением ограничений SQLite 400 миллионов записей должны быть в порядке.
Каковы характеристики производительности sqlite с очень большими файлами базы данных?
Я лично использую LMDB и привязку python для несколько миллионов записей DB. Это чрезвычайно быстро даже для базы данных, большей, чем оперативная память. Он встроен в процесс, поэтому сервер не нужен. Зависимость управляется с помощью pip.
Единственным недостатком является то, что вы должны указать максимальный размер БД. LMDB собирается в mmap файл такого размера. Если слишком мало, вставка новых данных вызовет ошибку. В целом вы создаете разреженный файл.