найти несколько слов по буквам из ввода в текстовом файле - PullRequest
0 голосов
/ 18 марта 2019

Я новичок в Python (более или менее), и я борюсь с одной задачей, где мне нужно ввести одно предложение либо с помощью пользовательского ввода, либо любым способом, который лучше / проще (желательно длинный, например, "Мы встретились"). вчера ", но не имеет большого значения). Затем выполните итерацию по всем буквам, найдите все возможные буквенные комбинации упомянутых слов и найдите совпадения с ними в файле, который состоит из тысяч слов (примерно 4 МБ файла), каждое слово находится на отдельной строке, например:

fun
dog
whatever
coffee
cup

Я пошел с itertools.permutations и попытался перейти с set и intersection. Без лишних слов, вот мой код:

from itertools import permutations


def alpha_check():
    """check whether a sentence consists of only letters"""
    sentence = str.lower(input('Type something in: '))
    while not sentence.replace(' ', '').isalpha():
        print(f"You typed in {sentence!s}. Only letters A-Z allowed, not case sensitive.")
        sentence = input("Please, type something again: ")
    return sentence


def file_iter(sentence: str):

    my_set = set(line.strip() for line in open('file.txt'))
    word_list = set(sentence.split())
    for x in word_list:
        temp = list(permutations(x))
        for f in temp:
            print(''.join(f), end=' ') # gets rid of commas etc.
        inters = my_set.intersection(f)
        return inters


print(file_iter(alpha_check()))

На данный момент альфа-проверка меня не интересует, мне бы хотелось, чтобы этот монстр заработал. В настоящее время он выводит что-то вроде этого, если я введу "map lake" после запроса:

Type something in: map lake
lake laek lkae lkea leak leka alke alek akle akel aelk aekl klae klea kale kael kela keal elak elka ealk eakl ekla ekal {'l', 'e', 'a', 'k'}

и ожидаемый результат будет map и lake перестановок, а затем найдены пересечения внутри ввода и файла. Я много искал на SO и Google. Нашел много информации, но я все равно не смог сделать эту работу. Это лучший, который я придумал. Также я не прошу полного решения, просто за помощь, чтобы понять, что я делаю неправильно, и как я могу решить это. Подсказки, советы и пр. Спасибо!

Обновление:

def file_iter(sentence):
    new_sentence = []
    my_set = set(line.strip() for line in open('file.txt'))
    word_list = sentence.split()
    for words in word_list:
        permutation = list(permutations(words))
        permute_set = my_set.intersection(["".join(word) for word in permutation])
        new_sentence += permute_set.union(word_list)

    return print(' '.join(set(new_sentence)))

Это обеспечивает вывод ниже:

Type something in: we met each other
toher ache we haec throe other tem each theor ew met thore

Как я могу получить их в разных предложениях? Что-то вроде этого:

we toher met ache
ew tem haec thore 

1 Ответ

0 голосов
/ 19 марта 2019

Я предполагаю, что под «найти все возможные буквенные комбинации указанных слов» вы на самом деле имели в виду перестановки. Если это так, то вы хотите сохранить большой список слов в словаре с отсортированными буквами в качестве ключа и списком соответствующих слов (анаграмм) в качестве значений.

Затем вы можете просмотреть слова в предложении и найти запись в словаре (используя отсортированные буквы слова), чтобы получить все анаграммы.

Сортированные буквы (wordKey) могут служить идентификатором группы для слов, являющихся анаграммами друг друга. Все анаграммы приведут к единственному ключу в словаре, поэтому вам не нужно беспокоиться о перестановках.

  • озеро - (сортировка букв) -> aekl: [озеро, утечка, капуста]
  • утечка - (сортировка букв) -> aekl: [озеро, утечка, капуста]
  • капуста - (сортировка букв) -> aekl: [озеро, утечка, капуста]

    Каждое слово достигает группы анаграмм, к которым оно относится, в словаре

Вот пример, из которого вы можете построить свое решение:

anagrams = dict()
for word in open("/usr/share/dict/words").read().split("\n"):
    wordKey = "".join(sorted(word.lower()))
    anagrams.setdefault(wordKey,[]).append(word)

sentence = "We met each other yesterday"
for word in sentence.split():
    wordKey = "".join(sorted(word.lower()))
    print(word, anagrams.get(wordKey,[word]))

Исходя из словаря 235K слов на моем ноутбуке, получается следующий вывод:

We ['we']
met ['met']
each ['ache', 'each', 'haec']
other ['other', 'thore', 'throe', 'toher']
yesterday ['yesterday']

Обратите внимание, что ваше решение было близко к работе.

  • Переменная f в my_set.intersection(f) должна была быть temp потому что f это просто последняя перестановка.
  • Также f, вероятно, не содержал того, что вы ожидали. Поскольку permutation(x) рассматривает x как список, он выдает результат (temp) это список списков, а не список строк.
  • Так что если вы измените его на my_set.intersection([ "".join(f) for f in temp]), оно, вероятно, будет работать.
  • Это хороший пример того, как выбирать значимые имена для вашего Переменные помогают избежать ошибок.
  • Мне также интересно, вернется ли inters после обработки только первое слово из набора предложений действительно то, что вы хотели сделать.
  • Последняя часть напечатанного результата также подозрительна, поскольку подразумевает, что вы действительно нашли пересечение с отдельным человеком. буквы слова «утечка». Это будет означать, что ваш файл содержит отдельные буквы или что вы не читаете его с соответствующая кодировка (например, Unicode читается как ASCII). Вы должны напечатать len(my_set) или первые несколько записей list(my_set)[:25], чтобы сделать уверен, что там есть слова, а не буквы.

[ОБНОВЛЕНИЕ] Представление вывода в виде единого списка слов:

sentence = "We met each other yesterday"
result = []
for word in sentence.split():
    wordKey = "".join(sorted(word.lower()))
    result += anagrams.get(wordKey,[]) + [word]
print(" ".join(set(result)))

# thore each other haec we met throe toher yesterday ache

[ОБНОВЛЕНИЕ2] Прикольные предложения

Если вы хотите поиграть с результатом и построить все предложения, которые могут быть сформированы с использованием анаграмм, вам нужно будет пройти через группу анаграмм каждого слова и «умножить» комбинации на каждом шаге:

from itertools import product
from itertools import product
funkySentences = [[]]
for word in sentence.split():
    wordKey        = "".join(sorted(word.lower()))
    alternateWords = anagrams.get(wordKey,[word])
    funkySentences = [ s+[w] for s,w in product(funkySentences,alternateWords) ]

funkySentences = set(" ".join(fs) for fs in funkySentences)   
for fs in funkySentences:
    print(fs)

Будет напечатано:

we met haec throe yesterday
we met haec thore yesterday
we met haec toher yesterday
we met ache toher yesterday
we met haec other yesterday
we met each throe yesterday
we met each toher yesterday
we met ache other yesterday
we met each thore yesterday
we met ache throe yesterday
we met ache thore yesterday
we met each other yesterday

Вы также можете сойти с ума и изменить порядок слов, применив перестановки к каждому из этих забавных предложений:

from itertools import chain,permutations
yodaSentences = chain(*[permutations(fs.split()) for fs in funkySentences])

yodaSentences = set(" ".join(ys) for ys in yodaSentences)
for ys in yodaSentences:
    print(ys)

Будет напечатано (говорит Йода):

ache we yesterday met other
other haec we met yesterday
yesterday met throe each we
haec throe yesterday met we
we yesterday met haec toher
yesterday we ache met throe
haec yesterday we other met
other yesterday met haec we
met we haec thore yesterday
each we yesterday other met
we ache yesterday other met
yesterday met toher we each
we met yesterday thore ache
... and many more ....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...