Может ли кто-нибудь помочь мне понять этот код (разбор таблицы HTML в lxml, python)?

Предыстория: мне нужно написать анализатор html-таблиц на python для HTML-таблиц с различными colspan и rowspan. После некоторых исследований я наткнулся на этот драгоценный камень. Это хорошо работает для простых случаев без дурацких colspan и rowspan, однако я столкнулся с ошибкой. В коде предполагается, что если элемент имеет colspan, равный 3, он принадлежит трем разным заголовкам таблицы, в то время как на самом деле он принадлежит только тому заголовку таблицы, в центре которого находится colspan. Пример этого можно увидеть на странице http://en.wiktionary.org/wiki/han#Swedish (откройте таблицу склонений в разделе Шведский). Код неправильно возвращает, что "hans" (притяжательный средний род мужского рода от 3-го лица) принадлежит мужскому роду притяжательного-общего-3-го лица и мужскому роду притяжательно-множественного числа от 3-го лица, потому что он имеет colspan 3. Я попытался добавить проверку в table_to_2d_dict, который создаст счетчик, если colspan > 1, и только подсчитает элемент как часть заголовка, если счетчик был равен colspan // 2 + 1 (это возвращает медиану диапазона (1, colspan+1), который является значением заголовок таблицы, за который следует считать элемент). Однако, когда я реализую эту проверку в месте, указанном в приведенном ниже коде, она не работает. Честно говоря, это, вероятно, связано с моим непониманием того, как работает этот код, так что...

Вопрос. Кто-нибудь может объяснить, что делает этот код и почему он работает неправильно, как описано выше? Если кто-то может реализовать исправление, это было бы здорово, но сейчас меня в первую очередь интересует понимание кода. Спасибо

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

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from collections import defaultdict


def table_to_list(table):
    dct = table_to_2d_dict(table)
    return list(iter_2d_dict(dct))


def table_to_2d_dict(table):
    result = defaultdict(lambda : defaultdict(str))
    for row_i, row in enumerate(table.xpath('./tr')): #these double for loops iterate over each element in the table
        for col_i, col in enumerate(row.xpath('./td|./th')):
            colspan = int(col.get('colspan', 1)) #gets colspan attr of the element, if none assumes it's 1
            rowspan = int(col.get('rowspan', 1)) #gets rowspan attr of the element, if none assumes it's 1
            col_data = col.text_content() #gets raw text inside element

            #WHAT DOES THIS DO? :(
            while row_i in result and col_i in result[row_i]: 
                col_i += 1
            for i in range(row_i, row_i + rowspan):
                for j in range(col_i, col_i + colspan):
                    result[i][j] = col_data
    return result

#what does this do? :(
def iter_2d_dict(dct):
    for i, row in sorted(dct.items()):
        cols = []
        for j, col in sorted(row.items()):
            cols.append(col)
        yield cols


if __name__ == '__main__':
    import lxml.html
    from pprint import pprint

    doc = lxml.html.parse('tables.html')
    for table_el in doc.xpath('//table'):
        table = table_to_list(table_el)
        pprint(table)

person Jane Doe    schedule 10.12.2013    source источник