Стеллаж Python с предметами, которых нет в списке

Я сохранил кучу словарей в файл, используя Python shelve модуль (с Python 3.4 на OSX 10.9.5). каждый key это строка типа int (например, "84554") и каждый value это словарь словарей из нескольких маленьких строк.

Ни один ключ не используется дважды, и я знаю полный набор всех возможных ключей. Я добавляю эти пары ключ-значение в shelf через потоки и то, какие ключи / значения добавляются, меняется каждый раз, когда я запускаю его (что ожидается).

Проблема, с которой я столкнулся, заключается в том, что количество ключей, повторяемых / видимых shelve"s shelf.keys() и количество уникальных ключей для которых key in shelf.keys() разные.

Вот мой код Я сначала инициализирую вещи и загружаю ids, который является списком всех возможных ключей.

import shelve 
from custom_code import *
MAIN_PATH = "/Users/myname/project_path/src/"
ids = list(set(load_list(MAIN_PATH + "id_list.pkl")))
c = c2 = 0
good_keys = []
bad_keys = []

Затем я открываю полку, считая все количество ключей, с которыми я перебираю db.keys(), добавив "хорошие" ключи в список.

db = shelve.open(MAIN_PATH + "first_3")
for k in db.keys():
    c2+=1
    good_keys+=[k]

Затем я проверяю каждый возможный ключ, чтобы увидеть, находится ли он на полке, проверяю, существует ли он на полке, и делаю то же самое, что и выше.

for j in set(ids):
    if j in db.keys():
        c+=1
        bad_keys+=[j]

Два счетчика, c а также c2, должно быть то же самое, но делать:

print("With `db.keys()`: {0}, with verifying from the list: {1}".format(c2, c))    

выходы:

With `db.keys()`: 628, with verifying from the list: 669

Затем я смотрю на ключи, которые были в bad_keys но нет good_keys (то есть, собранные из db.keys()) и выберите пример.

odd_men_out = list( set(bad_keys).difference( set(good_keys) ) )
bad_key = odd_men_out[0] 
print(bad_key) # '84554'

Затем я проверяю следующее:

print(bad_key in db.keys()) # True
print(bad_key in db)  # True
print(db[bad_key]) # A dictionary of dictionaries that wraps ~12ish lines
print(bad_key in list(db.keys())) # False

Обратите внимание, что последняя проверка. Кто-нибудь знает, что дает? я думал shelves должен был быть легким, но это дало мне полный ад.

Возможно, не связанное (но, возможно, нет), когда я позволяю еще большему количеству записей накапливаться на полке и пытаюсь сделать что-то вроде for k in db.keys() или же list(db.keys())Я получаю следующую ошибку:

  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/_collections_abc.py", line 482, in __iter__
    yield from self._mapping
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/shelve.py", line 95, in __iter__
    for k in self.dict.keys():
SystemError: Negative size passed to PyBytes_FromStringAndSize

Но все же можете получить доступ к данным, попробовав все возможные ключи. Очевидно, это потому, что я не использую gdbm?

1 ответ

Когда я пытался сохранить некоторые массивы numpy с более чем 1000 элементами на моей полке, он сохранял только некоторые и полностью пропускал другие, не выдавая ошибки.

По-видимому, это проблема при использовании Shelve в Mac OSX (вот несколько отчетов об ошибках (https://bugs.python.org/issue33074 , https://bugs.python.org/issue30388).

Единственным простым решением, которое я нашел, было использование Pickle вместо Shelve .

Другие вопросы по тегам