How to insert one or more character in the middle of a string using python?

Viewed 257

I wanted to list all the associative operation possible for an n-elements group. For example, when n=3, I want it to print:

a*(a*a)  =  (a*a)*a
a*(a*b)  =  (a*a)*b
a*(a*c)  =  (a*a)*c
... 24 more lines

Now, my best attempt to produce these is the following python3 code.

import itertools as it

def permutation_func(str_, rep):
  chars = list(str_)
  results = []
  for tuple_ in it.product(chars, repeat = rep):
    i = ''.join(tuple_)
    results.append(i)
  return results
 
my_list = permutation_func('abc', 3)

for i in my_list:
    print(i, " = ", i)

However, the output I am getting is:

aaa  =  aaa
aab  =  aab
aac  =  aac
... and 24 more lines

I think I am on the right track. But I cannot figure it out how to transform aaa = aaa to a*(a*a) = (a*a)*a which is basically I need to insert the * sign and the parentheses multiple times inside the text.

I have tried googling and I found that I need regular expressions to do this. However, I never used regular expression. So I am looking for an alternative that does not use regular expression. I don't even know whether it is possible without regular expression. If it is not, let me know please.

2 Answers

Unfortunatelly, strings in Python are not mutable objects - so you just can insert a character in a position. (And regular expressions would not help - they have a fancy mechanism for replacing some text, and while it would be possible to do the insertions you want with a call to re.sub, figuring out the correct regexp and a callback function to do this would not be worth it)

On the other hand, Python's lists are sequences that can be arbitrarily changed. And fortunately, there is a simple mechanism to convert strings to lists and back. Once you have a list, you can either use the .insert method, or slice assignment to insert your values:

a = "aaa"
b = list(a)
b.insert(1, "*")
b.insert(2, "(")
b.insert(4, "*")
b.insert(6,")")
c = "".join(b)

Given what you intend to do, maybe this is not the most practical way to do it - you probably should have a function that will get a sequence of tokens as input (which can be a list, or a string with one-letter tokens), and instructions on how to group and an interpolating character, and then return it as a string:

def group_tokens(tokens, start, end, join="*"):
    output = ""
    for index, token in enumerate(tokens):
        if index != 0:
            output += join
        if index == start:
            output += "("
        elif index == end:
            output += ")"
        output += token
    if end >= len(tokens):
        output += ")"
    return output

Based on the comments the following should work

for c1, c2, c3 in itertools.product('abc', repeat=3):
    print(f'({c1}*{c2})*{c3} = {c1}*({c2}*{c3})')

It prints:

(a*a)*a = a*(a*a)
(a*a)*b = a*(a*b)
(a*a)*c = a*(a*c)
... 24 more

If you replace the string with abcd, it will generate 64 entries.

Related