Python: словарь списка списков - PullRequest
3 голосов
/ 05 октября 2010
def makecounter():
     return collections.defaultdict(int)

class RankedIndex(object):
  def __init__(self):
    self._inverted_index = collections.defaultdict(list)
    self._documents = []
    self._inverted_index = collections.defaultdict(makecounter)


def index_dir(self, base_path):
    num_files_indexed = 0
    allfiles = os.listdir(base_path)
    self._documents = os.listdir(base_path)
    num_files_indexed = len(allfiles)
    docnumber = 0
    self._inverted_index = collections.defaultdict(list)

    docnumlist = []
    for file in allfiles: 
            self.documents = [base_path+file] #list of all text files
            f = open(base_path+file, 'r')
            lines = f.read()

            tokens = self.tokenize(lines)
            docnumber = docnumber + 1
            for term in tokens:  
                if term not in sorted(self._inverted_index.keys()):
                    self._inverted_index[term] = [docnumber]
                    self._inverted_index[term][docnumber] +=1                                           
                else:
                    if docnumber not in self._inverted_index.get(term):
                        docnumlist = self._inverted_index.get(term)
                        docnumlist = docnumlist.append(docnumber)
            f.close()
    print '\n \n'
    print 'Dictionary contents: \n'
    for term in sorted(self._inverted_index):
        print term, '->', self._inverted_index.get(term)
    return num_files_indexed
    return 0

Я получаю ошибку индекса при выполнении этого кода: список индекса выходит за пределы диапазона.

Приведенный выше код генерирует индекс словаря, который хранит термин в качестве ключа и номера документов, в которыхТермин встречается в виде списка.Например: если термин «кот» встречается в документах 1.txt, 5.txt и 7.txt, словарь будет иметь следующий вид: cat <- [1,5,7] </p>

Теперь я должен изменитьэто добавить частоту термина, поэтому, если слово cat встречается дважды в документе 1, трижды в документе 5 и один раз в документе 7: ожидаемый результат: term <- [[docnumber, term freq], [docnumber, term freq]] <--список списков в дикте !!!cat <- [[1,2], [5,3], [7,1]] </p>

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

Заранее спасибо.

Ответы [ 3 ]

6 голосов
/ 05 октября 2010

Сначала используйте фабрику.Начните с:

def makecounter():
    return collections.defaultdict(int)

и позже используйте

self._inverted_index = collections.defaultdict(makecounter)

и в качестве цикла for term in tokens:

        for term in tokens:  
                self._inverted_index[term][docnumber] +=1

Это оставляет в каждом self._inverted_index[term] диктнапример,

{1:2,5:3,7:1}

в вашем примере.Так как вы хотите вместо этого в каждом self._inverted_index[term] списке списков, то сразу после окончания цикла добавьте:

self._inverted_index = dict((t,[d,v[d] for d in sorted(v)])
                            for t in self._inverted_index)

После того, как сделано (так или иначе - я просто показываю простойспособ ее построения!), тогда эта структура данных будет на самом деле неудобной в использовании, поскольку вы, конечно, излишне затрудняете ее создание (конечно, диктат гораздо более полезен и прост в использовании, а также в создании), ноЭй, мужик, мясо & c; -).

1 голос
/ 05 октября 2010

Вот общий алгоритм, который вы можете использовать, но вам придется адаптировать к нему часть своего кода. Он создает словарь, содержащий словарь количества слов для каждого файла.

filedicts = {}
for file in allfiles:
  filedicts[file] = {}

  for term in terms:
    filedict.setdefault(term, 0)
    filedict[term] += 1
0 голосов
/ 05 октября 2010

Возможно, вы могли бы просто создать простой класс для (имя документа, частота).

Тогда ваш дикт может иметь списки этого нового типа данных.Вы также можете составить список списков, но отдельный тип данных будет чище.

...