Python: la sum no funciona en la syntax de la lista de comprensión si la fuente es el archivo

Soy un novato en Python y estoy estudiando la comprensión de la lista.

Lo que estoy tratando de hacer es convertir el siguiente código en una lista de comprensión:

def words_without_e(): count = 0 words = open('words.txt') for word in words: if word.find('e') == -1: count += 1 words.close() return count 

Aquí está mi débil bash:

 words = open('words.txt') print sum([1 for word in words if word.find('e') == -1]) 

Pero lamentablemente no está funcionando. La respuesta que espero obtener es 37641, pero obtengo 0. 🙁

Intenté crear otro código haciendo lo mismo pero en lugar de un archivo como fuente, usé una lista:

 def test(): words = ['hello', 'world', 'ciao'] return sum([1 for word in words if word.find('e') == -1]) 

Y funciona.

Vi esta publicación SO “bastante” similar e intenté que el código publicado allí return len([word for word in words if len(word) >= 2 and word[0] == word[-1]]) . Funciona si la fuente es una lista codificada, pero falla si la fuente es un archivo externo.

Ahora, mi pregunta es, ¿la sum solo funciona con listas y tuplas? Si entendiera los documentos correctamente, cualquier iterable podría resumirse.

Cualquier iluminación sería muy apreciada. 🙂

La solución más simple es esta:

 with open("words.txt") as words: sum(1 for word in words if "e" not in word) 

Como puede ver, la sum funciona con cualquier iterador, aquí estoy usando una expresión generadora.

En lugar de hacer word.find('e') == -1 , podemos simplemente hacer "e" not in word que sea más agradable de leer y que funcione, ya que las cadenas son iterables y admiten __contains__ .

También estoy utilizando la instrucción with para abrir archivos: es preferible abrirlos y cerrarlos manualmente, ya que maneja esas cosas por usted y las excepciones también.

Me gustaría señalar, sin embargo, su ejemplo funciona para mí. Mi conjetura es que su archivo está delimitado por espacios o comas, pero si recorre un archivo devuelve líneas.

Mi archivo de prueba:

 bob bill james test something no 

Esto, por ejemplo, no funcionará:

 bob bill james test something no 

Como obtendremos una cadena conteniendo todo el asunto. En este caso, podemos usar str.split() para dividir las líneas en palabras.

P.ej:

 with open("words.txt") as lines: sum(1 for line in lines for word in line.split() if "e" not in word) 

Acabo de probar esto y funciona, por lo que podría tener algo que ver con el formato del archivo:

 me@pc:~/Desktop$ cat > words.txt app noot mies wim zus jet me@ps:~/Desktop$ python Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) [GCC 4.4.5] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> sum(1 for word in open('words.txt') if 'e' not in word) 4 

Bueno. Probé el código que escribió @Lattyware y está funcionando bien. Creo que ya encontré al culpable, aunque no entiendo por qué se comporta de esa manera. Supongo que eso será para otra pregunta. 🙂

 def count_words(): with open("words.txt") as words: print sum(1 for word in words) print sum(1 for word in words if "e" not in word) >>> count_words() 113809 0 

Pero cuando comenté la primera statement impresa, muestra la respuesta correctamente.

 >>> count_words() 37641 

ACTUALIZAR:

Estoy publicando la solución que se me ocurrió por si alguien más encuentra el mismo problema.

 def count_words(): total = 0 wordsWithoutE = 0 with open("words.txt") as words: for word in words: if 'e' not in word: wordsWithoutE += 1 total += 1 return (total, wordsWithoutE) >>> print count_words() (113809, 37641)