martes, 17 de enero de 2017

Lista por comprensión en python para eliminar elementos repetidos

Eliminar los elementos repetidos en una lista python es posible mediante el siguiente algoritmo; donde se declara inicialmente una lista que se llena a medida que se cumple la condición establecida en el if del bucle que recorre la lista original.



1
2
3
4
5
6
7
8
9
my_list = [ 5, 3, 7, 3, 5, 5, 5, 2, 5, 7, 7, 3 ]

new_list = []

for element in my_list:
    if element not in new_list:
        new_list.append(element)

print new_list # produce [5, 3, 7, 2]

Sin embargo, cuando se pretende realizar algo similar en una lista por comprensión el algoritmo sólo funciona (produciendo la lista original) si se redunda en la declaración de la lista "recipiente".

1
2
3
4
5
6
7
my_list = [ 5, 3, 7, 3, 5, 5, 5, 2, 5, 7, 7, 3 ]

#new_list = [] #produce la lista original si se incluye esta linea 

new_list = [ element for element in my_list if element not in new_list ]

print new_list

Para hacer la autoreferencia de la manera adecuada hay que emplear una lista enumerada para la original.

1
 2
 3
 4
 5
 6
 7
 8
 9
10
my_list = [ 5, 3, 7, 3, 5, 5, 5, 2, 5, 7, 7, 3 ]

new_list = []

for x in enumerate(my_list):
    print x, my_list[:x[0]]
    if x[1] not in my_list[:x[0]]:
        new_list.append(x[1])

print new_list

En el código anterior se imprimen los valores de 'x' y 'my_list[:x[0]]', en cada paso del bucle, para comprender el por qué del algoritmo. Esto produce lo siguiente:

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
(0, 5) []
(1, 3) [5]
(2, 7) [5, 3]
(3, 3) [5, 3, 7]
(4, 5) [5, 3, 7, 3]
(5, 5) [5, 3, 7, 3, 5]
(6, 5) [5, 3, 7, 3, 5, 5]
(7, 2) [5, 3, 7, 3, 5, 5, 5]
(8, 5) [5, 3, 7, 3, 5, 5, 5, 2]
(9, 7) [5, 3, 7, 3, 5, 5, 5, 2, 5]
(10, 7) [5, 3, 7, 3, 5, 5, 5, 2, 5, 7]
(11, 3) [5, 3, 7, 3, 5, 5, 5, 2, 5, 7, 7]
[5, 3, 7, 2]

Ahora, con esta sintaxis es posible establecer una lista por comprensión en una sola línea que funciona. Es la siguiente:

1
2
3
4
5
my_list = [ 5, 3, 7, 3, 5, 5, 5, 2, 5, 7, 7, 3 ]

new_list = [ x[1] for x in enumerate(my_list) if x[1] not in my_list[:x[0]]]

print new_list # produce [5, 3, 7, 2]

Otra opción que funciona es la siguiente:

1
2
3
4
5
my_list = [ 5, 3, 7, 3, 5, 5, 5, 2, 5, 7, 7, 3 ]

new_list = [ my_list[i] for i in range(len(my_list)) if my_list[i] not in my_list[:i] ]

print new_list # produce [5, 3, 7, 2]



No hay comentarios: