Reputation: 681
I am trying to write a code that splits lists in a class of lists in two when a certain value is a middle element of the list and then produce two lists where the middle element becomes the end element in the first list and the first element in the second one.
There can be more than n middle elements in the list so the result must be n+1 lists.
Example:
A = [[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],[16,17,18,19,20,21,22,23,24,25],[26,27,28,29]]
P = [4,7,13,20]
n = len(Points) # in this case n = 4
I am looking for a result that looks like this:
A = [[0,1,2,3,4],[4,5,6,7],[7,8,9,10,11,12,13],[13,14,15],[16,17,18,19,20],[20,21,22,23,24,25],[26,27,28,29]]
Since n = 4 and it will produce 5 lists, note that the answer has 6 lists because the last list doesn't have any value of P in and therefore stays intact.
I haven't been able to produce anything as I am new to python and it is hard to formulate this problem.
Any help is appreciated!
Upvotes: 1
Views: 6541
Reputation: 22294
You can first recover all indices of the provided values and then slice accordingly.
def split_at_values(lst, values):
indices = [i for i, x in enumerate(lst) if x in values]
for start, end in zip([0, *indices], [*indices, len(lst)]):
yield lst[start:end+1]
# Note: remove +1 for separator to only appear in right side slice
values = {4, 7, 13, 20}
lst = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
print(*split_at_values(lst, values))
[0, 1, 2, 3, 4] [4, 5, 6, 7] [7, 8, 9, 10, 11, 12, 13] [13, 14, 15]
You can then apply this iteratively to you input list A
to get the desired result. Alternatively you can use itertools.chain.from_iterable
.
from itertools import chain
values = {4, 7, 13, 20}
lst_A = [[0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
[16, 17, 18, 19, 20, 21, 22, 23, 24, 25],
[26, 27, 28, 29]]
output = list(chain.from_iterable(split_at_values(sublst, values) for sublst in lst_A))
print(output)
[[0, 1, 2, 3, 4],
[4, 5, 6, 7],
[7, 8, 9, 10, 11, 12, 13],
[13, 14, 15],
[16, 17, 18, 19, 20],
[20, 21, 22, 23, 24, 25],
[26, 27, 28, 29]]
Upvotes: 4
Reputation: 106445
You can keep appending the sub-list items to the last sub-list of the output list, and if the current item is equal to the next item in Points
, append a new sub-list to the output with the same item and pop the item from Points
:
output = []
for l in List:
output.append([])
for i in l:
output[-1].append(i)
if Points and i == Points[0]:
output.append([i])
Points.pop(0)
With your sample input, output
would become:
[[0, 1, 2, 3, 4], [4, 5, 6, 7], [7, 8, 9, 10, 11, 12, 13], [13, 14, 15], [16, 17, 18, 19, 20], [20, 21, 22, 23, 24, 25], [26, 27, 28, 29]]
Upvotes: 0