Я вот подумал: представление языков в виде дерева не очень удобно, т.к. с поиском вхождения того или иного языка в список начинаются проблемы. Поэтому, довольно логичным шагом стало преобразовать список в первую нормальную форму, с ней будет работать проще всего. Текущий вид списка:
'type': u'Array language',
'wiki_link': u'A+ (programming language)'},
{'lang_name': u'APL',
'type': u'Array language',
'wiki_link': u'APL (programming language)'},
{'lang_name': u'Chapel',
'type': u'Array language',
'wiki_link': u'Chapel (programming language)'},
{'lang_name': u'Fortran', 'type': u'Array language', 'wiki_link': None},
{'lang_name': u'J',
'type': u'Array language',
'wiki_link': u'J (programming language)'},
{'lang_name': u'Julia',
'type': u'Array language',
'wiki_link': u'Julia (programming language)'},
{'lang_name': u'K',
'type': u'Array language',
'wiki_link': u'K (programming language)'},
{'lang_name': u'Matlab', 'type': u'Array language', 'wiki_link': None},
{'lang_name': u'S',
'type': u'Array language',
'wiki_link': u'S (programming language)'},
{'lang_name': u'X10',
'type': u'Array language',
'wiki_link': u'X10 (programming language)'},
{'lang_name': u'ZPL',
'type': u'Array language',
'wiki_link': u'ZPL (programming language)'}],
'name': u'Array language'}]
flatten_langs = []
for langs in langs_info:
for lang in langs['langs']:
lang['type'] = langs['name']
flatten_langs.append(lang)
return flatten_langs
В принципе, полученный код работает достаточно быстро, но меня гложут сомнения, может быть, проще всего сразу, на этапе построения списка преобразовывать? Кроме того, я пока что не очень понимаю принципов работы с памятью в Python. Например, будут ли в коде выше создаваться копии объектов или будут переиспользованы старые? Если говорить о скорости работы, то:
Добавление элемента в словарь должно выйти быстрее и предыдущий код построения списка языков можно просто переписать следующим образом:
result = []
lang_type = re.search('==\s*(.+[^\s*])\s*==', section)
lines = section.split('\n')
# * [[wiki_link | lang_name]]
r = re.compile('^\*+\s*(\[\[' # * or ** and [[
'((?P<wiki_link>[^[]*?)(\|))?' #optional wiki_link using lazy algorithm
'(?P<lang_name>[^{}]+?)'
'\]\])') # ]]
for line in lines:
lang = r.search(line)
if lang:
lang_rec = lang.groupdict()
lang_rec['lang_type'] = lang_type.group(1)
result.append(lang_rec)
return result
langs_info = []
for section in langs.sections[:-3]:
section_data = langs.section(section['index'])
lang_list = process_type(section_data)
langs_info += lang_list
Тем не менее, все это было не более чем подготовкой. Дальше я планировал загрузить данные в
Но, опять таки с учетом небольшого опыта работы с Pandas я мучаюсь сомнениями на тему того, нужно ли строить индексы
data_with_idx = data.set_index('lang_name') # (2)
В принципе,
lang_name | lang_type | wiki_link | |
---|---|---|---|
0 | A+ | Array language | A+ (programming language) |
1 | APL | Array language | APL (programming language) |
2 | Chapel | Array language | Chapel (programming language) |
3 | Fortran | Array language | None |
4 | J | Array language | J (programming language) |
5 | Julia | Array language | Julia (programming language) |
6 | K | Array language | K (programming language) |
7 | Matlab | Array language | None |
8 | S | Array language | S (programming language) |
9 | X10 | Array language | X10 (programming language) |
И проиндексированный DataFrame:
lang_type | wiki_link | |
---|---|---|
lang_name | ||
A+ | Array language | A+ (programming language) |
APL | Array language | APL (programming language) |
Chapel | Array language | Chapel (programming language) |
Fortran | Array language | None |
J | Array language | J (programming language) |
Julia | Array language | Julia (programming language) |
K | Array language | K (programming language) |
Matlab | Array language | None |
S | Array language | S (programming language) |
X10 | Array language | X10 (programming language) |
А вот плане скорости работы индексы позволяют ускорить код в ~2 раза:
Но! Если искать по тексту на прямую, то можно организовать регистронезависимый поиск, например, что тоже интересно, пусть и ощутимо медленнее:
Если говорить о данном конкретном примере, то, наверное, все равно, т.к. объем
данных очень не велик, но в случае больших объемов, ускорение в 2 раза может
оказаться существенным.