Reputation: 25
I want to find all words that have a particular set of target letters. My code works when none of the letters in the target is repeated, but not if there are repeats.
Here is my code:
target = 'bba'
target_words = [
'aani', 'aaru', 'abac', 'abas',
'abba', 'abby', 'abed', 'abel', 'abet'
]
target_list = list(target)
final_list = []
for word in target_words:
word_list = list(word)
if (all(x in word_list for x in target_list)):
final_list.append(word)
print('Final list: ', final_list)
The output is Final list: ['abac', 'abas', 'abba', 'abby', 'abed', 'abel', 'abet']
I would like it to be Final list: ['abba', 'abby']
I cannot find a way to get the result I want. It may be because I am converting the letters of the words into a list, but I don't see how to do it otherwise.
Upvotes: 1
Views: 91
Reputation: 19243
This is a good use case for collections.Counter()
. It gives us a clean way to check whether the desired overlap exists between a word in target_words
and the target
, accounting for duplicate letters (with a suggested improvement by azro):
from collections import Counter
target_counter = Counter(target)
[word for word in target_words if Counter(word) & target_counter == target_counter]
This outputs:
['abba', 'abby']
Upvotes: 3
Reputation: 36496
First let's find the unique letters in your target word.
target_word_letters = set(target)
Now, we can use a dictionary comprehension to get a count of each letter.
counts = {letter: target.count(letter) for letter in target_word_letters}
Now we need a list comprehension that iterates over target_words
and checks that for every letter in counts
, the same number (or more) of that letter is in the target word.
[word for word in target_words if all(word.count(l) >= c for l, c in counts.items())]
Result:
['abba', 'abby']
Upvotes: 0