Эффективный способ многократной замены в большой строке

Я хочу итеративно соединить несколько наборов символов в строке. Пример:

mystr = 'T h i s _ i s _ a _ s e n t e n c e'
joins = [('e', 'n'), ('en', 't'), ('i', 's'), ('h', 'is')]

# do multiple replace
for bigram in joins:
  mystr = mystr.replace(' '.join(bigram), ''.join(bigram))
print(mystr)
'T his _ is _ a _ s ent en c e'

В первой итерации он объединяет e n в en, затем en t в ent и так далее. Важно, чтобы соединения выполнялись по порядку, так как соединение ('en', 't') не работает, если ('e', 'n') не было соединено.

Со строкой из 20 МБ и 10 КБ соединений это занимает некоторое время. Я ищу, чтобы оптимизировать это, но я не знаю, как. Некоторые из вещей, которые я отбросил:

  • Я не использовал регулярное выражение, как в этом вопросе потому что я не знаю, как сделать re.sub, где подстановка представляет собой совпадение, но объединенное вместе
  • Я не использовал str.translate как этот вопрос либо потому, что, насколько мне известно, translate может переводить только отдельные символы, а в мой joins есть несколько

Есть ли какой-либо алгоритм, строка или регулярное выражение или любая другая функция, которая позволила бы мне это сделать? Благодарю вас!


person Ane    schedule 12.12.2020    source источник
comment
Похоже, ваш код на самом деле удаляет пробелы (' ') и ничего более. Если это так, почему бы вам просто не работать непосредственно с пробелами?   -  person IoaTzimas    schedule 12.12.2020
comment
Вы пытаетесь это сделать? mystr.replace(' ','').replace('_',' ')   -  person JenilDave    schedule 12.12.2020
comment
@IoaTzimas да, он удаляет пробелы, но только те, что вокруг биграмм, а не все пробелы   -  person Ane    schedule 14.12.2020


Ответы (1)


Прямой способ:

mystr = 'T h i s _ i s _ a _ s e n t e n c e'

bigrams = [('e', 'n'), ('en', 't'), ('i', 's'), ('h', 'is')]
for first_part, second_part in bigrams:
    mystr = mystr.replace(first_part + ' ' + second_part, first_part + second_part)
print(mystr)

Отпечатки:

T his _ is _ a _ s ent en c e

Второй способ:

mystr = 'T h i s _ i s _ a _ s e n t e n c e'

bigrams = [('e', 'n'), ('en', 't'), ('i', 's'), ('h', 'is')]
for bigram in bigrams:
    mystr = mystr.replace(' '.join(bigram), ''.join(bigram))
print(mystr)

Вам нужно будет сравнить два подхода.

person Booboo    schedule 12.12.2020
comment
разве это не именно то, что я сделал? с возможностью получить кортеж полностью или каждый элемент по отдельности, но это одно и то же, верно? - person Ane; 14.12.2020
comment
Да. Но что вам нужно сделать, так это взять подмножество ваших биграмм и/или меньшую строку и сравнить два способа выполнения замены и посмотреть, какой из них работает лучше. - person Booboo; 14.12.2020
comment
спасибо, я попробовал, и ваш первый подход немного медленнее, чем тот, который я сделал. Моя идея/цель состояла в том, чтобы был способ обойти цикл и сделать все замены в одном месте, но кажется, что цикл неизбежен. - person Ane; 14.12.2020