Rock
Rock

Reputation: 2977

Format string by binary list

With a string and a binary list of the same length, for example:

[0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0]
 s  t  a  c  k  o  v  e  r  f  l  o  w

Is it possible to obtain a new string as -t-c-over---- that follows:

[0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0]
 -  t  -  c  -  o  v  e  r  -  -  -  -

That is, each character matching with 0 will be replaced as -. The desired output would be a list as below with letters matching 1 and hyphens matching 0 are grouped separately:

['-', 't', '-', 'c', '-', 'over', '----']

Thanks!

Upvotes: 4

Views: 281

Answers (4)

Stephen
Stephen

Reputation: 2424

You could do this:

string = "stackoverflow"
arr = [0,1,1,0,1,0,1,0,1,0,0,1,0]
new = ""
for i in range(len(arr)):
    new += string[i]*arr[i] +"-"*(abs(arr[i]-1))

this exploits that a string times 0 is an empty string.

Then you could split it up into a list of strings using regex

import re
list = re.findall("-+|[A-z]+", new)

the "-+|[A-z]+" matches patterns that are either a string of dashes of length more than 1 or a string of letters of length more than 1.

Upvotes: 1

Abhijit
Abhijit

Reputation: 63737

The answer to your last Question could have been slightly modified to get the desired result

First Answer:

Given

[''.join(v) for k, v in groupby(st, key = lambda e:next(it_lst))]

Modified

[''.join(v if k else ('-' for _ in v)) 
 for k, v in groupby(st, key = lambda e:next(it_lst))]

Second Answer

Given

[''.join(zip(*v)[-1]) 
 for k, v in groupby(zip(lst, st), key = itemgetter(0)) if k]

Modified

[''.join(zip(*v)[-1] if k else ('-' for _ in v)) 
 for k, v in groupby(zip(lst, st), key = itemgetter(0))]

Note All you need to do is to

  1. Stop ignoring the 0 entries
  2. For Each 0 entries create a string of length equal to the grouped string under 0

Upvotes: 1

jurgenreza
jurgenreza

Reputation: 6086

How about something like this? Zip the two lists and iterate and build the output. Keep the last binary value to determine whether you should append or concat.

blist = [0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0]
string = 'stackoverflow'
output = []    
previous = not blist[0] # to cause the first char to be appended

for b,s in zip(blist, string):
    char = '-' if b == 0 else s

    if previous == b:
        output[-1] += char         
    else:
        output.append(char)

    previous = b

print(output)

Another option is regex:

import re

blist = [0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0]
string = 'stackoverflow'

x = ''.join(['-' if b == 0 else s for b,s in zip(blist, string)])
output = re.findall('(-+|[a-z]+)', x)

print(output)

Upvotes: 4

JBernardo
JBernardo

Reputation: 33397

You can have fun with iterators (no zip needed! :)

it = iter([0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0])
s = 'stackoverflow'

output = [''.join(('-' for i in b) if not a else b)
          for a,b in 
          itertools.groupby(s, key=lambda x: next(it))]

So output will be:

['-', 't', '-', 'c', '-', 'over', '----']

Upvotes: 3

Related Questions