On Mon, 6 Sep 2010 01:45:30 am William Allison wrote: > I'd like to write a program to help find words for Scrabble but I've > been having trouble > right from the beginning. > > tiles = 'aeirstw' > > dictionary = ['aardvark', 'cat', 'dog', 'taste', 'stare', 'wrist'] > > for word in range(len(dictionary)):
That's misleading -- "word" isn't a word at all, it's a number. > for letter in range(len(dictionary[word])): And likewise for letter. > if dictionary[word][letter] in tiles: > nothing here quite works Better to write that loop as: for word in dictionary: for letter in word: if letter in tiles: nothing here quite works either... > I guess what I'm trying to do is step through every letter of every > word in my dictionary > and if that letter is in my tiles set it aside and compare it back to > the dictionary. The approach I think you're trying to take is to find out if each letter in the tiles matches a word in the dictionary. Let's separate that functionality into a function of its own: def match(word, tiles): """Return true if every letter in word matches a tile.""" for letter in word: if letter not in tiles: # Mismatch, so fail. return False # if we get to the end, all the letters must have matched return True Let's test it: >>> match("ape", "axdeps") True >>> match("cat", "axdeps") False So far so good! But we can simplify it, because there's a built-in function that does the same thing: def match(word, tiles): """Return true if every letter in word matches a tile.""" return all(letter in tiles for letter in word) Don't worry too much about this though, because unfortunately this function, and my first version, have a logic bug: they fail to take into account repeated letters. >>> match("moon", "monabc") # Should give false. True Oops. Okay, let's think about the problem a bit more... it's not enough for each letter to be in the tiles, but that there must be at least as many copies as in the word. So, let's do another version: def match(word, tiles): """Return true if every letter in word matches a tile.""" for letter in word: if word.count(letter) > tiles.count(letter): return False return True >>> match("man", "monabc") True >>> match("moon", "monabc") False That looks better! It's not the most efficient code in the word, but for comparing small words and a small set of tiles, it's good enough -- there's no need to optimize the code at this early stage. Get it working first, then make it fast. So, putting it back together: for word in dictionary: if match(word, tiles): play_word() # whatever... -- Steven D'Aprano _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor