2011-05-27 23 views
5

me tienen dicho código:Python, trabajar con listas por comprensión

a = [[1, 1], [2, 1], [3, 0]] 

quiero conseguir dos listas, la primera contiene elementos de 'a', donde a[][1] = 1, y el segundo - en donde los elementos a[][1] = 0. Así

first_list = [[1, 1], [2, 1]] 

second_list = [[3, 0]]. 

puedo hacer tal cosa con dos listas por comprensión:

first_list = [i for i in a if i[1] == 1] 

second_list = [i for i in a if i[1] == 0] 

Pero tal vez exista otra (más Pythonic, o más corto) manera de hacer esto? Gracias por tus respuestas.

Respuesta

7

La comprensión de la lista es muy pitónica y la forma recomendada de hacerlo. Tu código está bien.

+0

acordado. Hay 2 listas/conjuntos de datos distintos, por lo tanto, se deben usar 2 comprensiones separadas. – Jordan

2

Puede utilizar sorted() y itertools.groupby() para hacer esto, pero no sé que sería calificar como Pythonic per se:

>>> dict((k, list(v)) for (k, v) in itertools.groupby(sorted(a, key=operator.itemgetter(1)), operator.itemgetter(1))) 
{0: [[3, 0]], 1: [[1, 1], [2, 1]]} 
+0

Parece más complicado que solo usar las comprensiones? Pero me encanta el uso de itertoos así que +1 –

+0

Más complicado, por cierto. Pero a medida que aumenta la cantidad de cosas que desea hacer con los datos, esta solución se vuelve más rápida, en términos relativos. –

+0

Como nota al margen ¿para qué sirve el operador? –

3

Si desea tenerlo en una sola línea se podría hacer algo como

first_list, second_list = [i for i in a if i[1] == 1], [i for i in a if i[1] == 0] 

Recuerda que "Explicit is better than implicit."

Su código está bien

0

qué pasa con esto,

In [1]: a = [[1, 1], [2, 1], [3, 0]] 

In [2]: first_list = [] 

In [3]: second_list = [] 

In [4]: [first_list.append(i) if i[1] == 1 else second_list.append(i) for i in a] 
Out[4]: [None, None, None] 

In [5]: first_list, second_list 
Out[5]: ([[1, 1], [2, 1]], [[3, 0]]) 

en lugar de dos sub-lista, yo prefiero dict (o defaultdict, OrderedDict, contador, etc.)

In [6]: from collections import defaultdict 

In [7]: d = defaultdict(list) 

In [8]: [d[i[1]].append(i) for i in a] 
Out[8]: [None, None, None] 

In [9]: d 
Out[9]: {0: [[3, 0]], 1: [[1, 1], [2, 1]]} 
+1

El uso de listas de comprensión estrictamente para los efectos secundarios es antiponético. –

+0

@lgnacio, de acuerdo, a veces puede ser más legible sin la comprensión de la lista (reemplázalo con un poco de estilo de bucle) – sunqiang

0

Si las listas son razonablemente cortas, entonces dos listas de comprensión funcionarán bien: no debe preocuparse por el rendimiento hasta que su código funcione y sepa que es demasiado lento.

Si las listas son largas o el código se ejecuta a menudo y que ha demostrado que es un cuello de botella entonces todo lo que tiene que hacer es cambiar de listas por comprensión a un bucle for:

first_list, second_list = [], [] 
for element in a: 
    if element[1] == 1: 
     first_list.append(element) 
    else: 
     second_list.append(element) 

que es ambos claros y fáciles de extender a más casos.

0

la lista de comprensiones son geniales. Si desea un código un poco más simple (pero un poco más largo), simplemente use un ciclo for.

Sin embargo, otra opción sería la de los filtros y los mapas:

a = [[1, 1], [2, 1], [3, 0]] 
g1=filter(lambda i: i[1]==1,a) 
g1=map(lambda i: i[0],g1) 
g2=filter(lambda i: i[1]==0,a) 
g2=map(lambda i: i[0],g2) 
print g1 
print g2 
Cuestiones relacionadas