Python - несколько вставок большого текста - PullRequest
1 голос
/ 17 декабря 2010

В Python, какой самый быстрый способ (то есть однопроходный метод) заключается в вставке двух больших наборов текста, A и B, в другой большой набор текста, C.

Где C, например:

.... ....
<<<A goes here>>>
.... ....
<<<B goes here>>>
.... ....

и "...." представляет довольно много текста (т.е. до 20 КБ).

Каков наилучший способ вставки A и B в соответствующие заполнители, где A и B также не являются «небольшими» объемами текста (т. Е. До 2k).

Моя первая мысль - сделать:

C.replace("<<<A goes here>>>", A)
C.replace("<<<B goes here>>>", B)

однако, так как он был пройден дважды, я надеюсь, что будет однопроходное решение. Я рассматривал регулярное выражение, но это кажется излишним. string.Template является опцией, но синтаксис не подходит (т. Е. $A - это заполнитель, который может иметь конфликты с другим текстом, а '$' не подходит для экранирования в другом месте).

В то время как заполнители A и B встречаются в C только один раз, я хотел бы иметь решение, которое масштабировалось бы до большего числа замен, т.е. независимо от числа замен; O (n), где n - это len (C).

Мысли и предложения приветствуются.

Спасибо.

Brian

Ответы [ 4 ]

3 голосов
/ 17 декабря 2010

Документация для str.find говорит, что она возвращает индекс первого вхождения искомой строки, что (для меня) подразумевает, что она не проходит всю строку.Если вы знаете, что "<<<A goes here>>>" всегда происходит первым, я бы сделал:

Aflag = "<<<A goes here>>>"
Bflag = "<<<B goes here>>>"
Aidx = C.find(Aflag)
Bidx = C.find(Bflag, Aidx+len(Aflag)+1)

newC = "".join((C[:Aidx], A, C[Aidx+len(Aflag)+1:Bidx], B, C[Bidx+len(Bflag)+1:]))

Если мое предположение верно, это минимизирует поиск по строке.

2 голосов
/ 17 декабря 2010

В зависимости от используемой версии Python вы можете использовать функцию format или оператор %.% работает везде, поэтому вот пример:

'...\n%s\n...\n%s\n...' % (a, b)

Это поместит содержимое a в первый %s и b во второй.

Итакпри условии, что вы можете изменить заполнители Си, превратить их в %s s, и все готово.

1 голос
/ 17 декабря 2010

самый быстрый не тот, о котором я думал! замена самая быстрая и простая

s = "\r\n"+("helllo"*100+"\r\n")*100
s2 = (s + "tag1" + s + "tag2" +s  + "tag2" + s + "tag1" + s)*10
t1= ("t1"*100+"\r\n")*100
t2= ("t2"*100+"\r\n")*100

print "size = ",len(s2)

def f1():
 return s2.replace("tag1",t1).replace("tag2",t2)

def f2():
 return "\r\n".join([ x.replace("tag1",t1).replace("tag2",t2) for x in s2.split("\r\n")])

m = {"tag1":t1,"tag2":t2}
def f3():
 p1 = 0
 res= ""
 while(p1 >= 0):
  p2 = s2.find("tag",p1)
  if (p2>=0):
   res+= s2[p1:p2]+m[s2[p2:p2+4]]
   p1 = p2+4
  else :
   res+= s2[p1:]
   p1 = -1
 return res


def g1():
 for i in range(100):
  f1()
def g2():
 for i in range(100):
  f2()

def g3():
 for i in range(100):
  f3()

if ( f1() != f2()):
 print "problem"
if ( f1() != f3()):
 print "problem"


import cProfile
cProfile.run('g1()')
cProfile.run('g2()')
cProfile.run('g3()')
1 голос
/ 17 декабря 2010

Вы можете применить любой из алгоритмов поиска строк, более конкретно KMP, который имеет O (n) время.Поскольку вы предполагали, что вы разделяете A и B, вы можете сделать это за один проход. Однако, вероятно, в конечном итоге это будет O (n + k), поскольку вам придется заменить строку, как только вы ее найдете.

http://en.wikipedia.org/wiki/String_searching_algorithm

http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm

Возможно, в Python есть гораздо более простой способ сделать это, с которым я не знаком, но если вы никогда не видели эти алгоритмы,Стоит взглянуть на.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...