简体   繁体   中英

In Python: How can i get my code to print out all the possible words I can spell based on my input?

I think I was close to figuring out how to print out all the possible words based on user input from my set dictionary. it's based on the assumption that the user input is 'ART' so the possible words I have in my dictionary are ART, RAT, TART, and TAR but only the three letter combinations are printing out. can anyone tell me where I am going wrong? Thanks!

Dictionary = ["tar","art","tart","rat"] #creates dictionary of set words
StoredLetters = input('input your word here: ') #allows the user to input any word
list(StoredLetters)

def characters(word):
    Dictionary = {}
    for i in word:
        Dictionary[i] = Dictionary.get(i, 0) + 1
    return Dictionary

def all_words(StoredLetters, wordSet):
    for word in StoredLetters:
        flag = 1
        words = characters(word)
        for key in words:
            if key not in wordSet:
                flag = 0
            else:
                if wordSet.count(key) != words[key]:
                    flag = 0
        if flag == 1:
            print(word)
if __name__ == "__main__":
    print(all_words(Dictionary, StoredLetters))

Based on the follow-up comments, the rule is that we must use all characters in the target word, but we can use each character as many times as we want.

I'd set up the lookup "dictionary" data structure as a Python dict which maps sorted, unique characters as tuples in each dictionary word to a list of the actual words that can be formed from those characters.

Next, I'd handle the lookups as follows:

  • Sort the unique characters of the user input (target word) and index into the dictionary to get the list of words it could make. Using a set means that we allow repetition and sorting the characters means we normalize for all of the possible permutations of those letters.
  • The above alone can give false positives, so we filter the resulting word list to remove any actual result words that are shorter than the target word. This ensures that we handle a target word like "artt" correctly and prevent it from matching "art" .

Code:

from collections import defaultdict

class Dictionary:
    def __init__(self, words):
        self.dictionary = defaultdict(list)

        for word in words:
            self.dictionary[tuple(sorted(set(word)))].append(word)

    def search(self, target):
        candidates = self.dictionary[tuple(sorted(set(target)))]
        return [x for x in candidates if len(x) >= len(target)]

if __name__ == "__main__":
    dictionary = Dictionary(["tar", "art", "tart", "rat"])
    tests = ["art", "artt", "ar", "arttt", "aret"]

    for test in tests:
        print(f"{test}\t=> {dictionary.search(test)}")

Output:

art     => ['tar', 'art', 'tart', 'rat']
artt    => ['tart']
ar      => []
arttt   => []
aret    => []

The issues in the original code have been addressed nicely in the other answers. The logic doesn't seem clear since it's comparing characters to words and variable names often don't match the logic represented by the code.

It's fine to use a frequency counter, but you'll be stuck iterating over the dictionary, and you'll need to check that each count of a character in a dictionary word is greater than the corresponding count in the target word. I doubt the code I'm offering is optimal, but it should be much faster than the counter approach, I think.

It appears there are a few things that could contribute to this.

  1. You are swapping the parameters on all words def allwords(Dictionary, StoredLetters): when you call it in main allwords(StoredLetters, Dictionary) . Without specifying the name (look up named parameters in python) you would be swapping the input.

  2. In the characters function it would appear you are resetting the dictionary variable. Try using unique names when creating new variables. This is causing the dictionary of words you set at the top to be emptied out when characters(word) is called

First off, you are confusing things by having the name of your variable StoredLetters also being the name of one of the arguments to your all_words function.

Second, you are actually passing in StoredLetters , which is art , as the 2nd argument to the function, so it is wordSet in the function, not StoredLetters !

You should really keep things more clear by using different variable names, and making it obvious what are you using for which argument. words isn't really words, it's a dictionary with letters as keys, and how many times they appear as the values. Making code clear and understandable goes a long way to making it easy to debug. You have word , StoredLetters , wordSet , another StoredLetters argument, words = characters(word) which doesn't do what is expected. This could all use a good cleanup.

As for the functionality, with art , each letter only appears once, so for tart , which has t twice, if wordSet.count(key) != words[key] will evaluate as True, and flag will be set to 0, and the word will not be printed.

Hope that helps, and happy coding!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM