Tengo la siguiente cadena y quiero decodificar filtrando las X

garbled = "IXXX aXXmX aXXXnXoXXXXXtXhXeXXXXrX sXXXXeXcXXXrXeXt mXXeXsXXXsXaXXXXXXgXeX!XX"

Y me gustaría filtrar. Probé el siguiente código

message = filter(lambda x: garbled.remove(x) if x == "X", garbled)

No hice que esto funcione. He encontrado esta otra solución:

message = filter(lambda x: x != "X", garbled)

Pero todavía me pregunto por qué no funcionó el primero. ¿Puedo arreglarlo?

(Soy nueva en python por cierto) gracias!

0
May Emanuel 30 oct. 2017 a las 14:53

4 respuestas

La mejor respuesta

filter(function, iterable) realiza el siguiente procedimiento:

  1. Revise los elementos en iterable (es decir, el segundo parámetro) uno a la vez.
  2. Para cada uno de esos elementos, llame a function (es decir, el segundo parámetro) en ese elemento y vea si devuelve verdadero.
  3. Reúna solo aquellos elementos donde function devuelva verdadero y devuelva una nueva lista de esos.

Mire lo que sucede en el paso 2 si pasa lambda x: garbled.remove(x) if x == "X" para el parámetro function: filter() se dice a sí mismo: "Hmm, si configuro x="I" entonces es {{X4} } ¿cierto?". Es como si estuvieras gritando una instrucción en filter() en su segundo parámetro: "oye, elimina todos los "X" s". Pero eso no es lo correcto para ir allí. Los requisitos son muy precisos: debe ser una función que tome un elemento y devuelva un valor verdadero o falso.

1
Arthur Tacca 30 oct. 2017 a las 12:28

Cory ya arregló su filter.

En mi opinión, su problema se maneja mejor con un simple str.replace.

>>> garbled = "IXXX aXXmX aXXXnXoXXXXXtXhXeXXXXrX sXXXXeXcXXXrXeXt mXXeXsXXXsXaXXXXXXgXeX!XX"
>>> garbled.replace('X', '')
'I am another secret message!'
1
timgeb 30 oct. 2017 a las 12:14
message = filter(lambda x: garbled.remove(x) if x == "X", garbled)

Este código no funciona, porque la función lambda debe ser expresión.

garbled.remove(x) if x == "X"

Esta es una declaración, no una expresión. Elimino si x == "X" para hacer una expresión válida,

message = filter(lambda x: garbled.remove(x), garbled)

A continuación, veo el error "el objeto 'str' no tiene ningún atributo 'eliminar'". Porque el tipo de ilegible es una cadena, y no hay ningún atributo que haya llamado 'eliminar' en el tipo de cadena. Para usar la función de filtro, el primer argumento debe ser la función 'predicado' (que devuelve Verdadero o Falso), y el segundo argumento debe ser iterativo. La segunda solución de OP satisface esta condición. el segundo argumento es una cadena que es iterable (una lista de caracteres), y el primer argumento es una función de predicado que toma un carácter que se proporciona desde la segunda cadena de argumento)

1
naoki fujita 30 oct. 2017 a las 12:31

Puede usar una expresión generadora en lugar de filter

>>> ''.join(i for i in garbled if i != 'X')
'I am another secret message!'

Si quisieras usar filter tendrías que cambiar tu lambda a

>>> ''.join(filter(lambda x: x != 'X', garbled))
'I am another secret message!'
5
CoryKramer 30 oct. 2017 a las 11:55