4

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!

8
  • 4
    Neat little problem. What have you tried? Commented Mar 2, 2013 at 1:36
  • @mgilson: Extracting letters matching 1 would be trivial but I have trouble replacing 0. Commented Mar 2, 2013 at 1:37
  • 1
    @Rock: Do you know how to iterate two sequences in lock step? Commented Mar 2, 2013 at 1:37
  • @abarnert: not sure. I guess using zip, right? Commented Mar 2, 2013 at 1:38
  • 1
    Exactly. What happens if you zip your string and binary list together? And then do, say, a for loop iterating over the result? Commented Mar 2, 2013 at 1:39

4 Answers 4

4

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)
Sign up to request clarification or add additional context in comments.

Comments

3

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', '----']

Comments

1

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

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.