简体   繁体   中英

(Python 3) Splitting a list using unique elements as separators

I have a list l=[2,3,4,5,6,99,7,8,9,10,11,12,100,13,14,15,16,17,18,101] and I will like to split l into sublists [2,3,4,5,6], [7,8,9,10,11,12],[13,14,15,16,17,18] , meaning that I use 'separator' digits 99,100,101 that belong to separators = [99,100,101] as a flag to indicate where I should go on to the next list.

In particular, these sublists may not have the same number of elements, but are different in size of only 1 (5 or 6). Note: There may be more than 3 separators.

Is there an efficient way to do this in Python 3? I thought of first extracting the indices of the separator elements and then slice the list accordingly but it seems far too complex and computationally intensive..

Some insight will be great!

Add on (suggestion from @Netwave): My attempt (which clearly does not work):

g = []
for i in l:
    if i in separators:
        g += [l[:l.index(i)]]

Output:

>>> g
[[2, 3, 4, 5, 6], [2, 3, 4, 5, 6, 99, 7, 8, 9, 10, 11, 12], [2, 3, 4, 5, 6, 99, 7, 8, 9, 10, 11, 12, 100, 13, 14, 15, 16, 17, 18]]

Use groupby :

from itertools import groupby

separators = [99, 100, 101]
l = [2, 3, 4, 5, 6, 99, 7, 8, 9, 10, 11, 12, 100, 13, 14, 15, 16, 17, 18, 101]

splits = [list(values) for key, values in groupby(l, key=lambda x: x not in separators) if key]

print(splits)

Output

[[2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]]

I hope you are looking for something similar to the below code. You need to iterate over your list and keep checking if the element is present in the separator list. This can be done other way around, as you said by iterating over the separator list and finding the index of the elements in the main list. For the sake of simplicity I took the former approach. (Make a note of the use of endindex variable):

l=[2,3,4,5,6,99,7,8,9,10,11,12,100,13,14,15,16,17,18,101]
seperator = [99,100,101]

list_of_list = []
endindex = 0
for i in range(0,len(l),1):
    if l[i] in seperator:
        list_of_list.append(l[endindex:i])
        endindex = i + 1

print(list_of_list)

Ouput:

[[2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]]

Easier for use in a function:

import itertools
def split(l,l2):
    return [list(v) for k,v in itertools.groupby(l,lambda x: x in l2) if not k]
l = [2, 3, 4, 5, 6, 99, 7, 8, 9, 10, 11, 12, 100, 13, 14, 15, 16, 17, 18, 101]
print(split(l,[99, 100, 101]))

Output:

[[2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18]]

Realized a duplicate of Split a list into nested lists on a value

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM