Home > Software engineering >  String slicing by index list
String slicing by index list

Time:09-29

I have a list of lengths present in a list, like:

a = [1, 3, 4]

Moreover, I have string who's length is exactly the sum of the numbers of a, here 8, looking like that:

s = "01100110"

I am looping over length of a and every time, I would like to have exactly the next n bits present in a. So here, it would be three runs, giving me "0", "110" and "0110".

Is there a very clever idea to do that efficient, for example by slicing? I have some weird complicated ways in my head but search for something more efficient.

Some solution I came up with:

counter_index = 0
counter_sum = 0

for i in range(len(a)):
   res = s[counter_sum:counter_sum a[counter_index]
   counter_sum  = a[counter_index]
   counter_index  = 1
   print(res)

CodePudding user response:

This approach basically updates the string each time it is sliced so we can get the next value by simply using the values in a as the index value directly instead of adding it to the existing position value.

a = [1, 3, 4]
s = "01100110"
st = s
i = 0
while i < len(a):
    print(st[:a[i]])
    st = st[a[i]:]
    i =1
 

Output

0
110
0110

CodePudding user response:

something like the below is the "slicing" solution to go with

a = [1, 3, 4]
s = "01100110"
offset = 0
for x in a:
    print(f'{s[offset: offset x]}')
    offset  = x

output

0
110
0110

CodePudding user response:

You can turn the string into an iterator. Then you can simply keep consuming it in the given chunk sizes:

it = iter(s)
["".join(next(it) for _ in range(chunk)) for chunk in a]
# ['0', '110', '0110']

You could make this yet more concise with itertools.islice:

from itertools import islice

it = iter(s)
["".join(islice(it, chunk)) for chunk in a]
['0', '110', '0110']

CodePudding user response:

I think the cleanest solution is to just loop over the indices in a directly, like so:

a = [1, 3, 4]
s = "01100110"
bgn = 0
for i in a:
    end = bgn   i
    # The wanted slice
    print(s[bgn:end])  # 0, 110, 0110
    # The next slice begins where this one left off
    bgn = end

If you need the results, you can pack them in a list:

a = [1, 3, 4]
s = "01100110"
results = []
bgn = 0
for i in a:
    end = bgn   i
    results.append(s[bgn:end])
    bgn = end
print(results)  # ['0', '110', '0110']

You could go for a list comprehension, but I think this would degrade the readability enough that it is not the right way to go.

CodePudding user response:

Edit as my initial response was wrong.

I = 0 # inital starting index
i = 0 # counter for len(a)
while i < len(a):
    J = sum(a[:i 1]) # second starting index
    print(s[I:J]) # or whatever function you need
    I = J # making starting index for next loop equal to this starting index
    i  = 1 # increment counter
0
110
0110
  • Related