1

At the moment this code takes in a string from a user and compares it to a text file in which many words are stored. It then outputs all the words that contain an exact match to the string. (E.G "otp = opt, top, pot) Currently when i input the string it only matches the string to the word with the EXACT same letters in a rearranged order.

My question is how do i go about being able to type in excess letters but still output all the words that are contained? for example: Type in "orkignwer" and the program will output "working" even though there are extra letters.

words = []


def isAnAnagram(word, user):
    wordList= list(word)
    wordList.sort()
    inputList= list(user)
    inputList.sort()
    return (wordList == inputList)

def getAnagrams(user):
    lister = [word for word in words if len(word) == len(user) ]
    for item in lister:
        if isAnAnagram(item, user):
            yield item


with open('Dictionary.txt', 'r') as f:
    allwords = f.readlines()
f.close()

for x in allwords:
    x = x.rstrip()
    words.append(x)
inp = 1


while inp != "99":
    inp = input("enter word:")
    result = getAnagrams(inp)
    print(list(result))     
2
  • 1
    You will likely want to use a Counter and then check that the input word has all the same letters (a.keys() == b.keys()) and that each letter has higher or equal counts b[k] > v for k, v in a.items(). Commented Mar 8, 2016 at 23:48
  • 1
    Aside: remember there's no need to close the file when using with. Commented Mar 8, 2016 at 23:48

1 Answer 1

1

You have to edit the isAnAnagram and the getAnagrams functions. First the getAnagrams function should be edited to also include the words of greater length in the lister list:

def getAnagrams(user):
    lister = [word for word in words if len(word) <= len(user) ]
    for item in lister:
        if isAnAnagram(item, user):
            yield item

Then you would need to edit the isAnAnagram function. As Alexander Huszagh pointed out, you can use the Counter from the collections package:

from collections import Counter

def isAnAnagram(word, user):
    word_counter = Counter(word)
    input_counter = Counter(user)
    return all(count <= input_counter[key] for key, count in word_counter.items())

The all(count <= input_counter[key] for key, count in word_counter.items()) checks to see if every letter of word appears in user at least as many times as they did in word.

P.S. If you want a more optimized solution, you might want to checkout TRIEs (e.g. MARISA-trie, python-trie or PyTrie).

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks everyone. I used your code changes bbkglb but it still does not output what i need. What i need is, for example, if i typed in "tpozxc" the prog would realise that there are 3 words in this and output "opt, top ,pot" but what is happening is it is ONLY outputting strings that match exactly in a re-arranged order, so to get top opt and pot i need to enter in a string with ONLY a combination of those letters.
@CBren Oh I see, I misunderstood your question then; I edited both of the functions. This should fix it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.