0

How to insert ' # ' for each n index from backward?
ex) n=4
evil = '01234567891234oooooooooooooooo321'
to
stan = '0#1234#5678#9123#4ooo#oooo#oooo#oooo#o321'
i tried using list with for,if statement, got stuck. something shameful like this

a = 1234567891234
b = [ a[-i] for i in range(1,len(a)+1)]
for i in range(len(b)):
    c += b[i]
    if i%4==0: #stuck
        c += ',' 
c.reverse()

What is the optimum way?

bbiot426
  • 37
  • 6
  • 1
    Could you add some of the code you've tried to question? – Emi OB Apr 28 '22 at 14:57
  • why is there a `#` after the first `0`? – Z Li Apr 28 '22 at 15:03
  • it's from backward, please see first line. – bbiot426 Apr 28 '22 at 15:05
  • Welcome to Stack Overflow. Given https://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks and https://stackoverflow.com/questions/1876191/what-exactly-does-the-join-method-do, can you see how to solve the problem? – Karl Knechtel Apr 28 '22 at 15:32
  • Do you actually want to insert `#`, or `,`? *Why* do you want to do this? If it's to format a number for some locale, does https://stackoverflow.com/questions/1823058/how-to-print-number-with-commas-as-thousands-separators help? – Karl Knechtel Apr 28 '22 at 15:35
  • Thank you, i was just curious about how f'{value:,}' works like – bbiot426 Apr 28 '22 at 15:44

7 Answers7

2

You might use a pattern asserting optional repetitions of 4 characters to the right, and replace that position with #

import re

pattern = r"(?=(?:.{4})*$)"
s = "01234567891234oooooooooooooooo321"
print(re.sub(pattern, "#", s))

Output

0#1234#5678#9123#4ooo#oooo#oooo#oooo#o321#

Python demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70
1

cut the string into chunks (backwards) and then concat them using the seperator

evil = '01234567891234oooooooooooooooo321'
l = 4
sep = '#'
sep.join([evil[max(i-l,0):i] for i in range(len(evil), 0, -l)][::-1])
'0#1234#5678#9123#4ooo#oooo#oooo#oooo#o321'
Z Li
  • 4,133
  • 1
  • 4
  • 19
0

You can do it like this:

evil = '01234567891234oooooooooooooooo321'
''.join(j if i%4  else f'#{j}' for i, j in enumerate(evil[::-1]))[::-1][:-1]

Output:

'0#1234#5678#9123#4ooo#oooo#oooo#oooo#o321'
Nin17
  • 2,821
  • 2
  • 4
  • 14
0

chunks function as in this answer

def chunks(lst, n):
    """Yield successive n-sized chunks from lst."""
    for i in range(0, len(lst), n):
        yield lst[i:i + n]

evil = '01234567891234oooooooooooooooo321'
n = 4
stan = "#".join(chunks(evil[::-1], n))[::-1]
print(stan) # Output: 0#1234#5678#9123#4ooo#oooo#oooo#oooo#o321

Input string is reversed ([::-1]), split into chunks, joined by "#" and then reversed back again. (It's possible to skip reverses if you calculate how many characters there will be in the first set of characters)

matszwecja
  • 6,357
  • 2
  • 10
  • 17
0

A naive solution would be using parts of evil string:

evil = '01234567891234oooooooooooooooo321'
n = 4
start = len(evil) % n
insert = '#'

stan = evil[:start] + insert
for i in range(start, len(evil) - n, n):
    stan += evil[i:i+n] + insert
stan += evil[-n:]
StSav012
  • 776
  • 5
  • 15
0

For this, I would go backwards through your string evil by reversing the string and iterating through it in a for loop. Then I set a count variable to keep track of how many loops it's done, and reset to 0 when it equals 4. All of this looks like the below:

count = 0
for char in evil[::-1]:
    if count == 4:
        count = 0
    count += 1

You can then establish a new empty string (new_str), and append each character of evil to, each time checking if count is 4, and adding a # to the string as well before resetting the count. Full code:

count = 0
new_str = ''
for char in evil[::-1]:
    if count == 4:
        new_str += '#'
        count = 0
    count += 1
    new_str += char

This will produce the new string reversed, so you need to reverse it again to get the desired result:

new_str = new_str[::-1]

Output:

'123o#oooo#oooo#oooo#ooo4#3219#8765#4321#0'
Emi OB
  • 2,814
  • 3
  • 13
  • 29
0

An exact method: use divmod to get the reminder and quotient of the string when divided in "blocks" of size 4 then slice.

evil = '01234567891234oooooooooooooooo321'

size = 4
q, r = divmod(len(evil), size)
sep = '#'
stan = f"{evil[:r]}{sep}{sep.join(evil[r+i*size: r+(i+1)*size] for i in range(q))}"

print(stan)

Remark: if the length of the string is a multiple of the block's size the new string will start with sep. Assumed as default behavior since lake of explanation

cards
  • 3,936
  • 1
  • 7
  • 25