Найти - Пользователи
Полная версия: разбор хитрого списка
Начало » Python для новичков » разбор хитрого списка
1 2
bystander
Здравствуйте, уважаемые форумчане, спасибо за помощь в прошлый раз.
Есть список вида:
город Курганск 128
Октябрьский район 53
ул. Ленина 15
ул. Пушкина 20
пер. Боксёров 0
во дворах и подворотнях 15
Портовый район 68
ул. Набережная 20
пер. портовый 3
пер. швартовый5
во дворах и подворотнях 40
Массив "Дубки" 10
ул. Героев обороны 8
во дворах и подворотнях 2
Город Ивановск (дальше перечисление районов и улиц, как и для прошлого города)

нужно из него сделать таблицу вида:
Курганск	Октябрьский	ул.	Ленина	15
Курганск	Октябрьский	ул.	Пушкина	20
Курганск	Октябрьский	пер.	Лумумбы	3
Курганск	Октябрьский	во дворах и подворотнях	во дворах и подворотнях	15

Для этого был написан скрипт, но он не работает (хотя по отдельности части, вроде, работают). Посмотрите, пожалуйста, в чём проблема:

x = open("C:\\startling_experiments\\data.txt", "r")
d = x.read().split('\n')
c = []  #Сюда запишется разаобранный список
t = {}  #Три уровня словарей: общий
tt = {} #по городам
ttt = {} #по районам
o = "город"   
a = "ПГТ"
v = "массив"
w = "район"
m = "ул."
n = "пер."
g = "и подворотнях"
for line in d:
    a = line.split(' ')
    f = [a[0], a[1], a[2]] #[город], [Курганск] [128] или [ул.] [Пушкина] [20] или[во дворах][и подворотнях][15]
    c.append(f)
  
for a_line in c:
    if o or a in str(a_line): #Если строка содержит "город" или "ПГТ"
        t[str(a_line[:-1])] = tt #то создаём ключ, например, город Курганск 
        for s_line in c[c.index(a_line) + 1:]: #и со следующей строки
            if v or w in str(s_line): #Если строка содержит "район" или "массив"
                tt[str(s_line[:-2])] = ttt #внутри основного словаря добавляем словарь с ключем Октябрьский
                for n_line in c[c.index(s_line) + 1:]: #и со следующей строки
                    if m or n in str(n_line): # если в строке "ул." или "пер."
                        ttt[str(n_line[:-1])] = n_line[-1] #ул. пушкина:20
                    elif g in str(n_line): # если "и подворотнях"
                        ttt[str(n_line[:-1])] = n_line[-1] #во дворах и подворотнях:15
                    elif v or w or o or a in str(n_line): #прерываем цикл поиска улиц, если встречаем новый район или город
                        break
            elif o or a in str(s_line): #прерываем цикл поиска районов, если находим новый город
                break
print(t)

И можно ли сделать это проще?
Budulianin
bystander
И можно ли сделать это проще?
Можно
Budulianin
bystander
Есть список вида:
Для каждого города фиксированное количество строк ?
bystander
В том-то и дело, что нет. Иначе можно было бы брать срезы с определённым шагом.
Я пытаюсь разобраться, почему не работает то, что есть.
Budulianin
Формат input.txt: каждый блок с инфой о городе разделяется пустой строкой

with open('input.txt', 'r') as f_in:
    lines = f_in.readlines()
city_block = {}
key = 0
for item in lines:
    if item=='\n':
        key += 1
        continue
    city_block.setdefault(key,[]).append(item)
with open('output.txt', 'w') as f_out:
   for item in city_block.keys():
       for city_line in city_block[item][2:]:
           line_format = ' '.join([city_block[item][0].split()[1],
           city_block[item][1].split()[0], city_line])
           f_out.write(line_format)
       f_out.write('\n')


Если формат файла такой как у тебя, то:

#coding: utf-8
with open('input.txt', 'r') as f_in:
    lines = f_in.readlines()
city_block = {}
key = -1
for item in lines:
    if item.decode('utf-8').lower().find(u'город')==0:
        key += 1
    city_block.setdefault(key,[]).append(item.decode('utf-8'))
with open('output.txt', 'w') as f_out:
   for item in city_block.keys():
       for city_line in city_block[item][2:]:
           line_format = ' '.join([city_block[item][0].split()[1],
           city_block[item][1].split()[0], city_line])
           f_out.write(line_format.encode('utf-8'))
       f_out.write('\n')

Только кодировка у input.txt должна быть utf-8
FishHook
bystander
В том-то и дело, что нет. Иначе можно было бы брать срезы с определённым шагом.Я пытаюсь разобраться, почему не работает то, что есть.
Откуда берутся данные? Если из файла, то как они попадают в файл? Если данные чужие, то какова их изначальная структура? Может быть стоит где-то раньше оптимизировать?
bismigalis
вообще какой-то ад и Паскаль

if o or a in str(a_line):

работает не так как ты думаешь
bystander
Budulianin:
Спасибо, буду разбираться, как это работает.
FishHook:
Исходный документ - txtшный файл на 150 мб, выдранный вручную из пдф и приведённый в более-менее однородный вид с помощью регулярных выражений в нотпаде++
bismigalis:
Я заметил, но почему, и как будет корректно? многократное повторение вроде if o in str(a_line) or a in str(a_line):, кажется, работает немного лучше.

Просто пытаюсь понять, где допустил ошибку я. Если пойму логику, то смогу избежать ошибок в дальнейшем. Не судите строго, я совершенно не айтишник, просто пытаюсь самостоятельно чему-то учиться, чтобы автоматизировать некоторые рабочие задачи.
Budulianin
bystander
выдранный вручную из пдф

Сразу pdf обрабатывай в Python

bismigalis
bystander
if o in str(a_line) or a in str(a_line):

вот так правильно

только, зачем преобразовывать в строку каждый раз, там и так строка
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB