Rahul
Rahul

Reputation: 11550

Split list by sub-string in item and preserving delimiter

This is the input:

[
    '@imp_Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    '@imp_Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    '@imp_Some_String',
    'Some_String',
    'Some_String'
]

This is the desired output

[
    [
        '@imp_Some_String',
        'Some_String',
        'Some_String',
        'Some_String',
        'Some_String'
    ],
    [
        '@imp_Some_String',
        'Some_String',
        'Some_String',
        'Some_String'
    ],
    [
        '@imp_Some_String',
        'Some_String',
        'Some_String'
    ]
]

The idea is to split the list if item startswith('@imp') I tried but the my solution will create x,y problem here.

Thanks.

Upvotes: 1

Views: 90

Answers (5)

Sunitha
Sunitha

Reputation: 12015

Join all the list elements into a single line, split it based on your delimiter @imp, add the delimiter back to the beginning of each line that resulted because of the split, and finally split each line based on space

>>> list(map(str.split, ('@imp'+s for s in ' '.join(lst).split('@imp') if s)))
[['@imp_Some_String', 'Some_String', 'Some_String', 'Some_String', 'Some_String'], ['@imp_Some_String', 'Some_String', 'Some_String', 'Some_String'], ['@imp_Some_String', 'Some_String', 'Some_String']]

Upvotes: 1

sahasrara62
sahasrara62

Reputation: 11228

k= [
    '@imp_Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    '@imp_Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    '@imp_Some_String',
    'Some_String',
    'Some_String'
]
from itertools import groupby
sol =[]
kk =[list(v) for  k,v in groupby(k)]
sol =[kk[i] + kk[i+1]for i in range(0,len(kk)-1,2)]

output

[['@imp_Some_String',
  'Some_String',
  'Some_String',
  'Some_String',
  'Some_String'],
 ['@imp_Some_String', 'Some_String', 'Some_String', 'Some_String'],
 ['@imp_Some_String', 'Some_String', 'Some_String']]

Upvotes: 1

Rakesh
Rakesh

Reputation: 82765

Using a simple iteration

Ex:

data = [
    '@imp_Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    '@imp_Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    '@imp_Some_String',
    'Some_String',
    'Some_String'
]

result = []
for i in data:              #Iterate items
    if i.startswith("@"):   #Check if item startswith "@"
        result.append([i])  #Append new list with item
    else:
        result[-1].append(i)   #Append item to previous list

print(result)

Output:

[['@imp_Some_String',
  'Some_String',
  'Some_String',
  'Some_String',
  'Some_String'],
 ['@imp_Some_String', 'Some_String', 'Some_String', 'Some_String'],
 ['@imp_Some_String', 'Some_String', 'Some_String']]

Using itertools.groupby

Ex:

from itertools import groupby
data = [
    '@imp_Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    '@imp_Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    '@imp_Some_String',
    'Some_String',
    'Some_String'
]

data = [list(v) for _, v in groupby(data, lambda x: x.startswith("@"))]
result = [i + v for i, v in zip(data[0::2], data[1::2])]

Upvotes: 2

Viktoriia Kachanovska
Viktoriia Kachanovska

Reputation: 125

Your current list:

list_ = [
    '@imp_Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    '@imp_Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    '@imp_Some_String',
    'Some_String',
    'Some_String'
]

Create list of indexes:

indexes = [ind for ind, el in enumerate(list_) if el.startswith('@imp')]

Get result:

res = [list_[i: j] for i, j in zip([0] + indexes, indexes + [None]) if i != j]

print(res) # [['@imp_Some_String', 'Some_String', 'Some_String', 'Some_String', 'Some_String'], ['@imp_Some_String', 'Some_String', 'Some_String', 'Some_String'], ['@imp_Some_String', 'Some_String', 'Some_String']]

Upvotes: 0

Andrej Kesely
Andrej Kesely

Reputation: 195438

One possible solution with itertools.groupby:

l = [
    '@imp_Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    '@imp_Some_String',
    'Some_String',
    'Some_String',
    'Some_String',
    '@imp_Some_String',
    'Some_String',
    'Some_String'
]

from itertools import groupby

out = [[*g] for _, g in groupby(l, lambda k, d={'g':0}: (d.update(g=d['g']+1), d['g']) if k.startswith('@imp') else (None, d['g']))]

from pprint import pprint
pprint(out, width=30)

Prints:

[['@imp_Some_String',
  'Some_String',
  'Some_String',
  'Some_String',
  'Some_String'],
 ['@imp_Some_String',
  'Some_String',
  'Some_String',
  'Some_String'],
 ['@imp_Some_String',
  'Some_String',
  'Some_String']]

Upvotes: 0

Related Questions