Форум успешных вебмастеров - GoFuckBiz.com

  Форум успешных вебмастеров - GoFuckBiz.com > Бизнес-решения > Скрипты, программы и технические решения
Дата
USD/RUB58.9640
BTC/USD0.0000
Скрипты, программы и технические решения Обсуждаем скрипты, программы и новые технологии.

Закрытая тема
Опции темы Опции просмотра
Старый 27.09.2013, 10:01   #1
gosu
Senior Member
 
Регистрация: 18.08.2009
Сообщений: 244
Бабло: $44521
По умолчанию парсинг 2 файлов

Взываю к силе гофака

Есть вот такая задача

Есть 2 файла txt

file1.txt
имеет строки вида:

key1±file1_random1
key2±file1_random2
key3±file1_random3



file2.txt
имеет строки вида:

file2_random2±key2
file2_random1±key1
file2_random3±key3


нужно брать 1 часть строки до разделителя ± из файла key1.txt
искать совпадение во второй части строки файла key2.txt

писать результат в 3 файл в таком виде

file1_random1|file2_random1|key1
file1_random2|file2_random2|key2
file1_random3|file2_random3|key3


В 1 файле 20к строк, во втором 150к строк

Пробовал на зенке, при зацикливание умирает через n времени
при чтении каждый раз заного файла очень медленно

Решение бы на пхп или перле идеально
gosu вне форума  
Старый 27.09.2013, 12:00   #2
Sheikh
Ебланнед
 
Регистрация: 26.05.2007
Сообщений: 754
Бабло: $155618
По умолчанию

да можно на зенке сделать, без зацикливания, если медленно работает, попробуй файлы порезать на несколько частей, на час делов там
Sheikh вне форума  
Старый 27.09.2013, 13:20   #3
editeur
Senior Member
 
Регистрация: 27.09.2013
Сообщений: 620
Бабло: $89330
По умолчанию

на питоне 2.x
Код:
# -*- coding: utf-8 -*-

f1= 'file1.txt'
f2 = 'file2.txt'
f3 = 'file3.txt'
delim = '±'

list1 = (a.strip().split(delim) for a in open(f1))
dict2 = dict(tuple(reversed(a.strip().split(delim))) for a in open(f2))

fout = open(f3, 'w')

for k, v in list1:
    k2 = dict2.get(k, None)
    if k2:
        fout.write("%s|%s|%s\n" % (v, k2, k))
Суть в том, чтобы не просматривать каждый раз второй файл с начала до конца, а преобразовать его в хэш-таблицу в RAM, 150к элементов это немного. Сложность алгоритма при этом меняется с O(N*M) на O(N+M).
editeur вне форума  
Старый 27.09.2013, 13:50   #4
gosu
Senior Member
 
Регистрация: 18.08.2009
Сообщений: 244
Бабло: $44521
ТС -->
автор темы ТС По умолчанию

Цитата:
Сообщение от editeur Посмотреть сообщение
на питоне 2.x
Код:
# -*- coding: utf-8 -*-

f1= 'file1.txt'
f2 = 'file2.txt'
f3 = 'file3.txt'
delim = '±'

list1 = (a.strip().split(delim) for a in open(f1))
dict2 = dict(tuple(reversed(a.strip().split(delim))) for a in open(f2))

fout = open(f3, 'w')

for k, v in list1:
    k2 = dict2.get(k, None)
    if k2:
        fout.write("%s|%s|%s\n" % (v, k2, k))
Суть в том, чтобы не просматривать каждый раз второй файл с начала до конца, а преобразовать его в хэш-таблицу в RAM, 150к элементов это немного. Сложность алгоритма при этом меняется с O(N*M) на O(N+M).
пооставил питон 2.7.5 на мак, запустил с лаунчера скрипт
выдало:
Traceback (most recent call last):
File "/file/script.py", line 13, in <module>
for k, v in list1:
ValueError: need more than 1 value to unpack
gosu вне форума  
Старый 27.09.2013, 13:59   #5
editeur
Senior Member
 
Регистрация: 27.09.2013
Сообщений: 620
Бабло: $89330
По умолчанию

Значит есть пустые строки или строки без разделителя
Попробуй так
Код:
# -*- coding: utf-8 -*-
f1= 'file1.txt'
f2 = 'file2.txt'
f3 = 'file3.txt'
delim = '±'

list1 = (b for b in (a.strip().split(delim) for a in open(f1)) if len(b) == 2)
dict2 = dict(tuple(reversed(b)) for b in (a.strip().split(delim) for a in open(f2)) if len(b) == 2)

fout = open(f3, 'w')

for k, v in list1:
    k2 = dict2.get(k, None)
    if k2:
        fout.write("%s|%s|%s\n" % (v, k2, k))
editeur вне форума  
Старый 27.09.2013, 14:08   #6
gosu
Senior Member
 
Регистрация: 18.08.2009
Сообщений: 244
Бабло: $44521
ТС -->
автор темы ТС По умолчанию

Цитата:
Сообщение от editeur Посмотреть сообщение
Значит есть пустые строки или строки без разделителя
Попробуй так
Код:
# -*- coding: utf-8 -*-
f1= 'file1.txt'
f2 = 'file2.txt'
f3 = 'file3.txt'
delim = '±'

list1 = (b for b in (a.strip().split(delim) for a in open(f1)) if len(b) == 2)
dict2 = dict(tuple(reversed(b)) for b in (a.strip().split(delim) for a in open(f2)) if len(b) == 2)

fout = open(f3, 'w')

for k, v in list1:
    k2 = dict2.get(k, None)
    if k2:
        fout.write("%s|%s|%s\n" % (v, k2, k))
Exit status: 0
logout
Ошибок нет
file3.txt пустой
gosu вне форума  
Старый 27.09.2013, 14:10   #7
editeur
Senior Member
 
Регистрация: 27.09.2013
Сообщений: 620
Бабло: $89330
По умолчанию

Значит разделитель другой, не ±
editeur вне форума  
Старый 27.09.2013, 14:15   #8
gosu
Senior Member
 
Регистрация: 18.08.2009
Сообщений: 244
Бабло: $44521
ТС -->
автор темы ТС По умолчанию

Сорри, работает скрипт
Спасибо!
1 из файлов оказался в левой кодировке

Последний раз редактировалось gosu; 27.09.2013 в 14:20.
gosu вне форума  
Старый 29.09.2013, 01:42   #9
editeur
Senior Member
 
Регистрация: 27.09.2013
Сообщений: 620
Бабло: $89330
По умолчанию

Да не за что
Только сейчас посмотрел личку с твоими сообщениями
Благодарности не нужны, забей, скрипт я так для собственного развлечения написал, там 5 минут работы
editeur вне форума