Python: как найти уникальную строку и проанализировать многострочный текст, связанный с найденной строкой?

Я пытаюсь проанализировать многострочные блоки текста из очень большого файла .txt (более 300 000 строк) и записать эти блоки текста в новый файл. Каждый блок текста, который мне нужен, состоит из 42 строк, и первая строка каждого 42-строчного блока начинается с уникального названия языка.

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

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

from sys import argv

script, from_file, to_file = argv

# Opens input/output files
infile = open(from_file).read()
outfile = open(to_file, 'w')


# Appends all unique language names into a list
langList = []
with open('language-list.txt') as file:
    for language in file:
        name = language.strip()
        langList.append(name)

# Pseudo code of what I want to do
for l in langList:
    find l in infile
    copy 42 lines beginning with match l
    write to outfile

Вот пример файла language-list.txt:

CENTRAL_GOJAL_WAKHI
TURKMEN

Основной текстовый файл можно скачать здесь: http://email.eva.mpg.de/~wichmann/listss16.zip

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

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


person acd    schedule 16.09.2014    source источник
comment
Я не совсем понимаю проблему, но обычно на любой вопрос, связанный с уникальными и связанными значениями фраз, в ответе используется словарь.   -  person Kevin    schedule 16.09.2014


Ответы (3)


Обычно я этого не делаю, но так как у меня слабость к лингвистике и лингвистам, то вот:

import re

swadesh = {}
lang = None

with open('/tmp/listss16.txt') as fp:
    for line in fp:
        m = re.match(r'(\d+)\s+\w+\s+([^/]+)', line)
        if m:
            if lang:
                swadesh[lang][int(m.group(1)) - 1] = m.group(2).strip()
            continue
        m = re.match(r'([A-Z]\w+){', line)
        if m:
            lang = m.group(1)
            swadesh[lang] = [''] * 100
            continue

Это создает dict lang_name : list, например.

LITHUANIAN : ['aS', 'yus, tu', 'mes', 'Sitas', 'anas, tas', 'kas, kuris', 'kas', 'ne', 'visas, visi', 'daugelis', 'vienas', 'du, div', 'didelis, platus', 'ilgas, letas', 'maZas, maZutis', 'moteris', 'Zmogus', 'asmuo, Zmogus', 'Zuvis', 'paukStis', 'Suo', 'utele', 'medis', 'sekla, grudas', 'lapas', 'Saknis', 'Zieve', 'oda, kailis', 'mesa, kunas', 'krauyas, giminy~ste', 'kaulas', 'taukai, riebalai', 'kiauSinis', 'ragas', 'uodega, eile', 'plunksna', 'palukas', 'galva', 'ausis', 'akis', 'nosis, nuyautimas', 'burna', 'dantis', 'lieZuvis', 'nagas', 'koya, peda', 'kelis', 'ranka', 'pilvas, skramdis', 'kaklas', 'krutine', 'Sirdis', 'kepeny~s', 'ger, girtau', 'valgy~, iSes', 'kas, gel', 'maty~, Ziure', 'girde, iSklausy~ti', 'Zino, paZin', 'miegas', 'mir', 'uZmuS, nuZudy~', 'plaukio', 'skris, pralek', 'ei, vaikSCio', 'atei, atvy~k', 'gule, bu', 'sede, posedZiau', 'stove, atsisto', 'duo, dovano', 'nuomone, Zodis', 'saule', 'menulis', 'ZvaigZde, Sviesuly~s', 'vanduo', 'lietus', 'akmuo', 'smely~s', 'Zeme', 'debesy~s', 'dumai', 'ugnis, liepsna', 'pelenai', 'deg', 'takas, kelelis', 'kalnas', 'raudonas, paraudes', 'Zalias, nesubrendes', 'geltonas', 'baltas', 'yuodas, tamsus', 'naktis', 'karStas', 'Saltas, abeyingas', 'pilnas, visas', 'nauyas, SvieZias', 'geras, malonus', 'apskritas, apvalus', 'sausas', 'vardas']
KHWARSHI : ['do', 'mo', 'ilo', '', '', '', '', '', '', '', 'hos', 'qw"X$inE', '', '', '', '', '', '%Xadam', 'CuXa', '', 'XXw$E', 'noc"o', 'Xon', '', 'tL~ib', '', '', 'qX~al', '', 'e*q"X~o', 'tL~ozol', '', '', 'SEly~u', '', '', '', '', 'a*hX~a', 'Ezol', 'ma*ni', '', 's3l', 'muc', '', '', 'gurtu', 'litL"a', '', '', 'koko', '', 'Zubu', 'c"oda', '', '', 'aka', 'tuqX~a', '', '', 'uha', '', '', '', '', 'ok"a', '', '', '', '', '', 'buqXX$', '', 'ca', 'Lo', '', 'Xur', '', '', '', '', 'c"o', '', '', 'hu*nE', 'hu*n', '', '', '', '', '', 'rELa', '', '', 'lec"u', 'uc"nu', '', '', '', 'co']
MANDARIN_2 : ['wo', 'ni', 'women', '', '', '', '', '', '', '', 'yi', 'er', '', '', '', '', '', 'ren', 'yu', '', '%gow', 'Sizi, towSi', 'Su', '', 'yezi', '', '', 'pi', '', 'Sie, Swe', 'gu tow', '', '', 'jiao', '', '', '', '', 'erduo', 'yanjiN', 'bizi', '', 'ya, yaCi', 'Setow', '', '', 'Si, Sigai', 'Sow', '', '', 'rufaN', '', 'gan, ganzaN', 'he', '', '', 'jian', 'tiN', '', '', 'si', '', '', '', '', 'lai', '', '', '', '', '', 'taiyaN', '', 'SiNSiN', 'Sui', '', 'Sitow', '', '', '', '', 'huo', '', '', 'xiaolu', 'Ciu, CiuliN', '', '', '', '', '', 'ye', '', '', 'man', 'Sin', '', '', '', 'miNzi, SiNmiN']
WARAO : ['ine', 'zatu', 'oko', 'tamaha', 'tai', 'sina', 'bitu', 'XXX', 'kokotuka', 'era', 'hishaka', 'manamu', 'irija', 'bumija', 'sanuka', 'tija', 'nibora', 'warau', 'homakaba', 'domu', 'beroro', 'ami', 'dau', 'amu', 'dau aroko', 'XXX', 'ahoro', 'horo', 'toma', 'hotu', 'muhu', 'toi', 'ahi', 'akw~ahoi', 'ahu', 'huhi', 'hio', 'kw~a', 'kohoko', 'mu', 'hikoto', 'doko', 'i', 'hono', 'kahanobo, mohusi', 'omu', 'mukuru', 'moho', 'obono', 'do', 'ami', 'kobe', 'mahi', 'takatakaza', 'nahoroza', 'basia', 'mia', 'nokoza', 'naminaza', 'ubaza', 'wabaza', 'naza', 'soitia', 'nebiria', 'naria, za*tia', 'nauza', 'zahia', 'duhuya', 'kanamuya', 'muaza', 'dibu', 'za', 'waniku', 'kura', 'ho', 'naha', 'hozo', 'huhu', 'hobahi', 'nahamutu', 'hehuku', 'hekunu', 'hekohuhu', 'ehohuya', 'hohisi', 'hotakw~ai', 'simo*', 'hebura', 'simosimo, johene', 'hokera', 'anera', 'ima', 'ihija', 'daitera, dehorohera', 'kw~atai', 'hijo', 'zakera', 'kobera', 'nauwaha', 'wai']
KAREN_GEBA : ['ya', 'na', 'pwa', '', '', '', '', '', '', '', 't3bw~a', 'Ci bw~a', '', '', '', '', '', 'by~a', 'ta ph~o', '', 'thw$i*7', 'tr~o7', 'tr~o7', '', 'La*7', '', '', '3ph~3i7', '', 'tr~wi*7', 'khw$i*7', '', '', 'ta 73no', '', '', '', '', 'k3ni7 ku', 'ka ka dr~u', 'k3ni kh~3de', '', 'kotr~o', 'k3pli', '', '', 'kh~a lo ma*7', 's3 kh~o', '', '', 'XXX', '', 'k3to tr~a*7', 'o', '', '', '3sa Ci', 'k3tr~a ha', '', '', 'tr~i', '', '', '', '', 'ke ba*7', '', '', '', '', '', 'lu mu', '', 'sya', 'Ci', '', 'lo7', '', '', '', '', 'mi7', '', '', 'kla*7 do7', 'kh~o la7', '', '', '', '', '', 'lu mu na kh~a, na kh~a', '', '', 'pw~a th~a*7', '3tr~a', '', '', '', 'k3sh~o7 mi']

Из этого словаря легко извлечь нужный язык (языки) или слово (слова).

person georg    schedule 16.09.2014
comment
Работает отлично! Здесь я выхожу за пределы своей зоны комфорта, поэтому я очень благодарен за помощь. - person acd; 16.09.2014

  1. 300 000 строк текста — это немного, и они легко умещаются в несколько 100 МБ. Если это не зависит от времени, сделайте это глупым способом и загрузите все это в список.

  2. Соберите все названия ваших языков в словарь, а не в список.

Затем переберите огромный текстовый файл:

for i, current_line in input_list:
    if current_line in languages:
        language_block = input_list[i:i + 43]
        # do something with it

Если у вас есть это, и вы хотите свести к минимуму потребление памяти, не загружайте весь файл, а перескакивайте через 42 строки, используя continue, перебирая все строки.

person Georg Schölly    schedule 16.09.2014

с readlines() в вашем открытом файле вы можете иметь индекс строк, поэтому:

infile = open('listss16.txt')
lines = infile.readlines()

for line in range(0,len(lines)):
    for l in langlist:
        if l in lines[line]:
            outfile.write(lines[line:line+42])

или один лайнер, чтобы написать раз и навсегда:

out = [lines[line:line+42] for l in langlist for line in range(0,len(lines)) if l in lines[line]]
person Hrabal    schedule 16.09.2014
comment
При запуске первоначального предложения я получил ошибку TypeError: ожидается объект символьного буфера. Насколько я понимаю это сообщение об ошибке, я пытаюсь написать список в файл outfile, а не строку. Разве readlines() не должен возвращать текст в виде строки? Один лайнер работал без ошибок, но создавал пустой документ. - person acd; 16.09.2014
comment
Да, извините, readlines() возвращает список строк, поэтому lines[line:line:42] - это список, поэтому для записи в файл вам нужно перебрать список ( [outfile.write(part) for part in lines[line:line+42] ). Один вкладыш возвращает список выбранных строк в файле. .. чтобы записать это в файл, вам нужно перебрать этот список и записать в файл элемент. - person Hrabal; 16.09.2014
comment
p.s: Я немного поигрался с файлами, которые вы связали, когда на работе.. имейте в виду, что если вы будете искать TURKMEN в файле, вы также найдете TURKMEN_2.. - person Hrabal; 16.09.2014
comment
Ах да имеет смысл. Спасибо, скрипт работает теперь, когда я перебираю список. Я также отметил появление TURKMEN_2 при написании этого примера, но спасибо! - person acd; 16.09.2014