Личный вызов понимания списка Python

Имея текстовый файл «words.txt», используйте понимание списка, чтобы прочитать все слова в файле и найти все слова, которые содержат по крайней мере 2 гласных.

Итак, у меня есть текстовый файл:

The quick brown fox jumps over the lazy dog

И лучшая попытка получить все слова и все слова с двумя или более гласными:

#This could be hardcoded in, but for the sake of simplicity (as simple as simplicity gets)
vowels = ["a","e","i","o","u"]
filename = "words.txt"
words = [word for word in open(filename, "r").read().split()]
multivowels = [each for each in open(filename, "r").read().split() if sum(letter in vowels for letter in each) >= 2]

Вывод должен имитировать:

All words in the file:  ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']
The words in the file that contain 2 or more vowels: ['quick', 'over']

Моя попытка поместить это в одну строку состояла в том, чтобы просто напечатать часть понимания списка «слов» и «многогласных», а также «Все слова в файле»; «... и т. д.

Есть ли кто-нибудь, кто решил бы объединить эти два понимания списков в одно? Мой товарищ по команде и я в тупике, но хотели бы показать это нашему профессору!

Опять же, мой окончательный однострочный код:

print "All words in the file: " + str([word for word in open(filename, "r").read().split()]) + "\nAll words with more than 2 vowels: " + str([each for each in open(filename, "r").read().split() if sum(letter in vowels for letter in each) >= 2])

РЕДАКТИРОВАТЬ: Моя попытка получить все слова в файле, а также все слова с двумя или более гласными.

vowels = ["a", "e", "i", "o", "u"]
filename = "words.txt"
print [(word, each) for word in open(filename, "r").read().split() if sum([1 for each in word if each in vowels]) >= 2]

person brettwbyron    schedule 30.06.2014    source источник
comment
зачем писать одной строкой? Это значительно усложняет отладку и удобочитаемость.   -  person redFIVE    schedule 30.06.2014
comment
Я бы не стал читать файл дважды.   -  person James Mills    schedule 30.06.2014
comment
Отдает ли ваш профессор должное тому, что другие решают проблему?   -  person martineau    schedule 30.06.2014
comment
Причина, по которой я написал это одной строкой, — просто доказать моему профессору, что я могу справиться с его задачами. Это абсолютно, несомненно, ужасный способ кодирования. Но он бросил мне вызов, так что я должен хотя бы попытаться! Это просто для удовольствия в этот момент. Я просто хотел посмотреть, есть ли у кого-нибудь понимание.   -  person brettwbyron    schedule 30.06.2014
comment
уже открытый файл можно сбросить с помощью .seek(0)   -  person karthikr    schedule 30.06.2014
comment
Это не для кредита. Просто чтобы прояснить, это просто глупый вызов от моего профессора. Я доказал ему, что понимаю понимание списка. Это просто дополнительная задача.   -  person brettwbyron    schedule 30.06.2014
comment
@karthikr Если я .seek(0), как я могу это применить?   -  person brettwbyron    schedule 30.06.2014
comment
используйте with open(filename, "r") as fh: и используйте fh.read() перед запуском второго понимания, сделайте fh.seek(0) и повторите   -  person karthikr    schedule 30.06.2014
comment
@karthikr И я смогу применить это с пониманием списка, например: words, mulitvowels = [(x, y) ...]   -  person brettwbyron    schedule 30.06.2014


Ответы (3)


Здесь есть несколько угловых случаев, но если вы предполагаете простой текстовый файл:

import re
vowels = "a","e","i","o","u"

answer = [[word for word in re.sub("[^\w]", " ",  sentence).split() if (sum(1 for letter in word if letter in vowels)>=2)] for sentence in open(filename,"r").readlines()]
person ebarr    schedule 30.06.2014

Итак, спасибо всем за ваш вклад. Было много действительно интересных подходов к поиску слов с двумя и более гласными. Сегодня утром я говорил со своим профессором о трудностях, которые у меня были с этой проблемой, и он прояснил мое недоразумение.

У меня сложилось впечатление, что он хотел, чтобы понимание единого списка возвращало список, содержащий список всех слов в файле, и список только слов с двумя или более гласными. Но на самом деле он просто хотел, чтобы я кончил; понимание списка для каждого сценария: все слова в файле; все слова в файле с двумя или более гласными.

Спасибо всем за ваш вклад!

person brettwbyron    schedule 30.06.2014

Я запустил немного другую версию с большим набором данных и обнаружил, что повторные вызовы str начинают складываться.

vowels = ['a', 'e', 'i', 'o', 'u']
#filename = 'vowelcount.txt'
filename = 'largetextfile.txt'
print "All words in the file: ", [w for w in open(filename).read().split()], "\n", "All words with more than 2 vowels: ", [w for w in open(filename).read().split() if sum(1 for l in w if l in vowels) > 1]

Вызов этой версии с cProfile показывает небольшое улучшение:

python -m cProfile vowelcount1.py

   7839 function calls in 0.023 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.005    0.005    0.023    0.023 vowelcount1.py:1(<module>)
     6045    0.009    0.000    0.009    0.000 vowelcount1.py:4(<genexpr>)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        2    0.000    0.000    0.000    0.000 {method 'read' of 'file' objects}
        2    0.000    0.000    0.000    0.000 {method 'split' of 'str' objects}
        2    0.000    0.000    0.000    0.000 {open}
     1786    0.009    0.000    0.018    0.000 {sum}

Код, который вы вставили, имеет почти вдвое больше вызовов функций:

#filename = 'vowelcount.txt'
filename = 'largetextfile.txt'
vowels = ['a', 'e', 'i', 'o', 'u']
print "All words in the file: " + str([word for word in open(filename, "r").read().split()]) + "\nAll words with more than 2 vowels: " + str([each for each in open(filename, "r").read().split() if sum(letter in vowels for letter in each) >= 2])

python -m cProfile vowelcount2.py

   14568 function calls in 0.036 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.004    0.004    0.036    0.036 vowelcount2.py:2(<module>)
    12774    0.016    0.000    0.016    0.000 vowelcount2.py:4(<genexpr>)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        2    0.000    0.000    0.000    0.000 {method 'read' of 'file' objects}
        2    0.000    0.000    0.000    0.000 {method 'split' of 'str' objects}
        2    0.000    0.000    0.000    0.000 {open}
     1786    0.016    0.000    0.032    0.000 {sum}

Как все уже очевидно заметили, это не то, как вы хотите писать код, который другим придется читать. Хотя я признаю, что вижу, как много я могу вместить в одно понимание python list тоже ради удовольствия :D

person tijko    schedule 30.06.2014