Estoy tratando de modificar una lista de dos listas. Para cada una de las dos listas internas, realizo algunas operaciones y las 'divido' en nuevas listas.
Aquí hay un ejemplo simple de lo que estoy tratando de hacer:

[['a', 'b'], ['c', 'd']]  -->  [['a'], ['b'], ['c', 'd']]

Actualmente mi algoritmo pasa ['a', 'b'] a una función que determina si debe dividirse o no en [['a'], ['b']] (por ejemplo, en función de sus correlaciones). La función devuelve [['a'], ['b']] que me dice que ['a', 'b'] debe dividirse o devuelve ['a', 'b'] (la lista original) que indica que no debe dividirse.

Actualmente tengo algo como esto:

blist = [['a', 'b'], ['c', 'd']]   #big list
slist =  [['a'], ['b']]            #small list returned by function

nlist = [items for i in xrange(len(blist)) for items in (slist if i==0 else blist[i])]

Esto produce [['a'], ['b'], 'c', 'd'] en oposición a la salida deseada [['a'], ['b'], ['c', 'd']] que no altera la segunda lista en la lista b original. Entiendo por qué sucede esto: mi segundo ciclo también se aplica a blist[1] en este caso, pero no estoy seguro de cómo solucionarlo, ya que no entiendo completamente la comprensión de la lista.

Se prefiere una solución 'pitónica'. Cualquier comentario sería apreciado, gracias!

EDITAR : como sugiere el título, estoy tratando de 'reemplazar' ['a', 'b'] con ['a'], ['b']. Por lo tanto, me gustaría que la 'posición' sea la misma, teniendo ['a'], ['b'] en la lista original antes de ['c', 'd']

RESULTADOS ¡Gracias Christian, Paul y schwobaseggl por sus soluciones! Todos trabajan :)

4
AsheKetchum 16 feb. 2017 a las 18:20

4 respuestas

La mejor respuesta

Puede usar la asignación de rebanadas:

>> l1 = [[1, 2], [3, 4]]
>>> l2 = [[1], [2]]
>>> l1[0:1] = l2
>>> l1
[[1], [2], [3, 4]]

Esto cambia l1, por lo que si desea conservarlo, haga una copia antes.

Otra forma que no cambia l1 es la adición:

>> l1 = [[1, 2], [3, 4]]
>>> l3 = l2 + l1[1:]
>>> l3
[[1], [2], [3, 4]]
1
Paul Panzer 16 feb. 2017 a las 16:02

Suponiendo que tiene la función mencionada que decide si dividir un elemento:

def munch(item):
    if item[0] == 'a': # split
        return [[item[0]], [item[1]]]
    return [item] # don't split

Puede usarlo en s simple for-loop.

nlist = []
for item in blist:
    nlist.extend(munch(item))

"Pythonic" es lo que sea fácil de leer y entender. No uses las comprensiones de listas solo porque puedas.

0
16 feb. 2017 a las 17:36

Puede modificar su función de división para devolver listas estructuralmente adecuadas. Entonces puedes usar una comprensión:

def split_or_not(l):
  if condition: # split
    return [l[:1], l[1:]]
  return [l]  # wrap in extra list

# using map
nlist = [x for sub_l in map(split_or_not, blist) for x in sub_l]
# or nested comprehension
nlist = [x for sub_l in (split_or_not(l) for l in blist) for x in sub_l]
1
schwobaseggl 16 feb. 2017 a las 15:49

Tratar

...  else [blist[i]])]

Para crear una lista de listas.

2
Christian König 16 feb. 2017 a las 15:24