1

I have to substitute substrings in a string if such substring belong to a list

txt = 'lorem ipsum; lorem ipsum. lorem ipsum: loren lorem'
list_punctuation = [', ',': ','; ']
for punct in list_punctuation:
    txt = txt.replace(punct,punct + '<<')

thats the tipical way. I loop through the elemtents of the list and make the substitution which consists on include a simbol "<<" after the punctuation.

The question is if there is a more pythonic way to do this. I dont like that loop and on top of being ugly it is probably very slow.

any idea?

EDIT1

Regex works. But I still think that there is a pythonic one liner without using external libraries (even if re is part of the standard one). Why do I refer a non-regex solution? because the list will be built separately and will change with the time. it is easier to change a list than the regex. I can not know now what the list will content. The punctuation list was a short example.

EDIT2 there are two links suggested in the answers.

a) the first one is about substitutions with conditions. There is no condition here, simply elements of a list. In this link a multiline solution is offer. My question is about finding a one liner. The aim of this question is finding a more concise solution.

How to replace multiple substrings of a string?

b) This question is about replacing characters and there is no reference to a list including the elements to substitute. in b) multiline coding is not a problem whereas here is exactly the problem. Best way to replace multiple characters in a string?

NOR a) or b) are solutions. But does not matter, this question was already blocked insisting in that there is a solution there.

JFerro
  • 3,203
  • 7
  • 35
  • 88
  • In both links together with this question you have a total of **36** answers. I am pretty sure they cover all the ways to do so. Also, "b" is exactly what you are describing. The fact that you have a list is merely a small detail to the fact that there are multiple characters to replace. BTW in that question there are 2 more links for other related questions – Tomerikoo Apr 20 '20 at 22:02
  • there is no single one liner solution refering to a list. I had a look to those questions already. a regex solution, being good, does not refer to a list. – JFerro Apr 20 '20 at 22:05
  • You can eaily translate [this answer](https://stackoverflow.com/a/6117124/6045800) to use a list – Tomerikoo Apr 20 '20 at 22:08
  • 1
    Like so: `pattern = re.compile(r"[{}]".format("".join(punctuation))))` – Tomerikoo Apr 20 '20 at 22:10
  • If I could "easly" translate a solution including regex, dictionaries, escapes, iteritems, compile, lambda, pattern, etcetc then I certainly wouldnt be here asking. – JFerro Apr 20 '20 at 22:11
  • thanks for the answer – JFerro Apr 20 '20 at 22:11
  • Well I didn't mean it like that. I meant that in the dups you have many answers and can adapt them to your needs – Tomerikoo Apr 20 '20 at 22:12
  • 1
    The dictionary used there is just to allow different replacement rules. But you have one rule: always add `<<`, so the dictionary boils down to a list – Tomerikoo Apr 20 '20 at 22:13
  • 1
    You can also use [that answer](https://stackoverflow.com/a/5012757/6045800) by doing again `punc_string = "".join(punct_list)` and you can even modify it to be on one line (if that matters...) or better yet, wrap the code in your question with a function and then call it with one line! – Tomerikoo Apr 20 '20 at 22:22

2 Answers2

1

Use a regular expression.

import re
txt = re.sub(r'[,:;] ', r'\g<0><<', txt)

\g<0> in the replacement is replaced with whatever matched the pattern.

Barmar
  • 741,623
  • 53
  • 500
  • 612
0

you can use re.sub:

import re
txt = 'lorem ipsum; lorem ipsum. lorem ipsum: loren lorem'

def my_s(g):
    return g.group() + '<<'

re.sub(r'[,:;] ', my_s, txt)

# 'lorem ipsum; <<lorem ipsum. lorem ipsum: <<loren lorem'
kederrac
  • 16,819
  • 6
  • 32
  • 55