Me gusta la comprensión de listas

Chema Cortés py en ch3m4.org
Jue Abr 24 10:41:52 CEST 2003


> > [L[i] for i in xrange(len(L)) if i%2==0][:100]  
>   
> No hace falta. Tienes un par de alternativas:  
>   
> [L[i] for i in range(len(L))[:100] if i%2==0]  
>   
> [L[i] for i in xrange(min(100, len(L))) if i%2==0]  

No hacen lo mismo. Estas expresiones sólo me sacarían una lista de 50
elementos.

> Aunque yo optaría por usar xrange o range con tres parámetros: 
>  
> [L[i] for i in xrange(0,min(100, len(L)),2)] 

Lo mismo. Esta expresión habría que cambiar el 100 por un 200.

Pero como decía en otro mensaje, es fácil estimar que con 200 elementos
de la lista obtendría los primeros 100 elementos en posición par. Yo
buscaba algo más genérico.

> De todos modos, Python 2.3 ofrecerá soluciones más elegantes. El operador 
> de corte se enriquece. Lo que propones se podrá hacer así (creo): 
>  
> L[0:100:2] 

Efectívamente, en 2.3 se ha implementado el operador de corte extendido
a las listas. Pero aquí el problema sigue siendo el mismo: sólo obtienes
50 elementos. Sería más correcto (aunque más costoso en recursos):

L[::2][:100]

> > Utilizando el enumerate() de python 2.3 y un hipotético operador de  
> > corte, sí que se podría hacer algo tal que así:  
> >   
> > [ L[fi] for (i,fi) in enumerate(fib()) while i<100 ]  
>   
> La cosa es fácil con generadores: 
>  
> >>> def fib(): 
> ...     a, b = 1, 1 
> ...     yield a 
> ...     while 1: 
> ...             a, b = b, a+b 
> ...             yield a 
> ... 
> >>> f = fib() 
> >>> [f.next() for i in range(10)] 
> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

Por aquí irían los tiros:

[L[i] for i in [f.next() for i in xrange(100)]]
[L[f.next()] for i in xrange(100)]

Aquí está el problema de que el generador podría estar "usado", y no
daría los resultados esperados (no me gusta tener que utilizar .next() ).


--
"Make free software, not war"




Más información sobre la lista de distribución Python-es