2012-07-04 10 views
5

Tengo una lista de cadenas y estoy tratando de hacer una lista de cadenas por longitud de cadena.Python: dividir la lista de cadenas en una lista de cadenas por longitud con una comprensión anidada

es decir

['a', 'b', 'ab', 'abc'] 

convierte

[['a', 'b'], ['ab'], ['abc']] 

que he logrado este modo:

lst = ['a', 'b', 'ab', 'abc'] 
lsts = [] 
for num in set(len(i) for i in lst): 
    lsts.append([w for w in lst if len(w) == num]) 

estoy bien con ese código, pero estoy tratando de envolver mi cabeza alrededor de las comprensiones. Quiero usar comprensiones anidadas para hacer lo mismo, pero no puedo entender cómo.

Respuesta

4
>>> [[w for w in L if len(w) == num] for num in set(len(i) for i in L)] 
[['a', 'b'], ['ab'], ['abc']] 

Además, itertools es probable que sea un poco más eficiente.

+1

Niza. Gracias. – dustin

0

Eso es para todas las longitudes de 1 a máximo (algunas de las listas estará vacía si no hay cuerdas de esa longitud en la lista a):

>>> a = ['a', 'b', 'ab', 'abc'] 
>>> m = max(len(x) for x in a) 
>>> print [[x for x in a if len(x) == i + 1] for i in range(m)] 
[['a', 'b'], ['ab'], ['abc']] 

Pero si usted quiere tener sólo listas para las longitudes que están en a debe usar set(len(i) for i in lst) en lugar de rango.

>>> print [[x for x in a if len(x) == i] for i in set(len(k) for k in a)] 
[['a', 'b'], ['ab'], ['abc']] 

No hay diferencia para la lista ['a', 'b', 'ab', 'abc']. Sin embargo, si cambia un poco, por ejemplo, por lo que: [['a', 'b'], ['ab'], ['abcd']], verá la diferencia:

>>> a = ['a', 'b', 'ab', 'abcd'] 
>>> print [[x for x in a if len(x) == i] for i in set(len(k) for k in a)] 
[['a', 'b'], ['ab'], ['abcd']] 

>>> print [[x for x in a if len(x) == i + 1] for i in range(max(len(x) for x in a))] 
[['a', 'b'], ['ab'], [], ['abcd']] 
1
lst = ['a', 'b', 'ab', 'abc'] 
lst.sort(key=len) # does not make any change on this data,but 
        # all strings of given length must occur together 


from itertools import groupby 
lst = [list(grp) for i,grp in groupby(lst, key=len)] 

resultados en

[['a', 'b'], ['ab'], ['abc']] 
+0

clasificación estable ... 'key = len' (también en groupby) – JBernardo

+0

@JBernardo: gracias, estaba pensando en eso pero me ganaste ;-) –

+1

Suelta el' lambda'. Simplemente hará que el código sea más lento – JBernardo

0
L=['a','b','ab','abc'] 
result = [ [ w for w in L if len(w) == n] for n in set(len(i) for i in L)] 
0
from itertools import groupby 

mylist = ['a', 'b', 'ab', 'abc'] 
[list(vals) for key, vals in groupby(mylist, lambda L: len(L))] 

nota que desde GroupBy solo funciona en elementos adyacentes; puede que necesite forzar una clasificación en mylist con key = len)

  • devuelve un iterador con la clave (que será la longitud) y vals, que es otro iterador que contiene datos en ese grupo de claves.
  • luego convierte el repetidor de datos en una lista
  • la lista queda fuera construido a partir de lo anterior

  • -
Cuestiones relacionadas