Tengo las siguientes listas x1, x2, x3, que quiero agrupar en las salidas respectivas mencionadas a continuación:

x1 = ['req', 'a', 'b', 'c', 'req', 'd', 'e', 'req', 'f']

expected_out1 = [['req', 'a', 'b', 'c'], ['req', 'd', 'e'], ['req', 'f']]

x2 = ['req', 'a', 'b', 'c', 'req', 'd', 'e', 'req', 'f', 'req']

expected_out2 = [['req', 'a', 'b', 'c'], ['req', 'd', 'e'], ['req', 'f'], ['req']]

x3 = ['req', 'a', 'b', 'c', 'req', 'd', 'e', 'req', 'req']

expected_out3 = [['req', 'a', 'b', 'c'], ['req', 'd', 'e'], ['req'], ['req']]

Escribí el siguiente código para abordar estos escenarios:

import numpy as np
def split_basedon_condition(b):
    num_arr = np.array(b)
    arrays = np.split(num_arr, np.where(num_arr[:-1] == "req")[0])
    return [i for i in [i.tolist() for i in arrays] if i != []]

Pero obtengo los siguientes resultados:

split_basedon_condition(x1)
actual_out1 = [['req', 'a', 'b', 'c'], ['req', 'd', 'e'], ['req', 'f']] # expected

split_basedon_condition(x2)
actual_out2 = [['req', 'a', 'b', 'c'], ['req', 'd', 'e'], ['req', 'f', 'req']] # not expected

split_basedon_condition(x3)
actual_out3 = [['req', 'a', 'b', 'c'], ['req', 'd', 'e'], ['req', 'req']] # not expected
0
sharathchandramandadi 26 may. 2020 a las 13:52

3 respuestas

La razón está en esta línea:

arrays = np.split(num_arr, np.where(num_arr[:-1] == "req")[0])

Al hacer num_arr[:-1] estás considerando num_arr con el último elemento desechado, por lo tanto, este comportamiento cuando "req" es el último elemento. Reemplace la línea anterior con:

arrays = np.split(num_arr, np.where(num_arr == "req")[0])

Y funcionará como una excepción para todos los casos de prueba que proporcionó.

Como nota al margen, si puede usar bibliotecas externas de Python que no sean numpy, puede aprovechar more_itertools.split_before para esa tarea.

0
Daweo 26 may. 2020 a las 11:05

Si el primero siempre es "req". Esta es una línea:

def func(l):
    return list(map(lambda x: x.insert(0, "req") or x, map(list, "".join(l[1:]).split("req"))))

Resultado:

[['req', 'a', 'b', 'c'], ['req', 'd', 'e'], ['req', 'f']]
[['req', 'a', 'b', 'c'], ['req', 'd', 'e'], ['req', 'f'], ['req']]
[['req', 'a', 'b', 'c'], ['req', 'd', 'e'], ['req'], ['req']]
0
jizhihaoSAMA 26 may. 2020 a las 11:34

Aquí hay una solución mucho más rápida de Python puro.

def split(arr, pred):
    j = len(arr)
    for i,_ in filter(lambda x: x[1] == pred, zip(range(j-1, -1, -1), reversed(arr))):
        yield arr[i:j]
        j = i

list(split(['req', 'a', 'b', 'c', 'req', 'd', 'e', 'req', 'req'], 'req'))
# [['req'], ['req'], ['req', 'd', 'e'], ['req', 'a', 'b', 'c']]
0
scicyb 26 may. 2020 a las 11:38