I wonder, if you open a text file in Python. And then you'd like to search of words containing a number of letters. 

Say you type in 6 different letters (a,b,c,d,e,f) you want to search.
You'd like to find words matching at least 3 letters.
Each letter can only appear once in a word.
And the letter 'a' always has to be containing. 

How should the code look like for this specific kind of search?
['https://Stackoverflow.com/questions/7518255', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/959397/']
Let's see...

```
return [x for x in document.split()
        if 'a' in x and sum((1 if y in 'abcdef' else 0 for y in x)) >= 3]

```

`split` with no parameters acts as a "words" function, splitting on any whitespace and removing words that contain no characters. Then you check if the letter 'a' is in the word. If 'a' is in the word, you use a generator expression that goes over every letter in the word. If the letter is inside of the string of available letters, then it returns a 1 which contributes to the sum. Otherwise, it returns 0. Then if the sum is 3 or greater, it keeps it. A generator is used instead of a list comprehension because sum will accept anything iterable and it stops a temporary list from having to be created (less memory overhead).

It doesn't have the best access times because of the use of `in` (which on a string should have an O(n) time), but that generally isn't a very big problem unless the data sets are huge. You can optimize that a bit to pack the string into a set and the constant 'abcdef' can easily be a set. I just didn't want to ruin the nice one liner.

EDIT: Oh, and to improve time on the `if` portion (which is where the inefficiencies are), you could separate it out into a function that iterates over the string once and returns True if the conditions are met. I would have done this, but it ruined my one liner.

EDIT 2: I didn't see the "must have 3 different characters" part. You can't do that in a one liner. You can just take the if portion out into a function.

```
def is_valid(word, chars):
    count = 0
    for x in word:
        if x in chars:
            count += 1
            chars.remove(x)
    return count >= 3 and 'a' not in chars

def parse_document(document):
    return [x for x in document.split() if is_valid(x, set('abcdef'))]

```

This one shouldn't have any performance problems on real world data sets.
```
words = 'fubar cadre obsequious xray'

def find_words(src, required=[], letters=[], min_match=3):
    required = set(required)
    letters = set(letters)

    words = ((word, set(word)) for word in src.split())
    words = (word for word in words if word[1].issuperset(required))
    words = (word for word in words if len(word[1].intersection(letters)) >= min_match)
    words = (word[0] for word in words)
    return words

w = find_words(words, required=['a'], letters=['a', 'b', 'c', 'd', 'e', 'f'])
print list(w)

```

**EDIT 1:** I too didn't read the requirements closely enough. To ensure a word contains only 1 instance of a valid letter.

```
from collections import Counter

def valid(word, letters, min_match):
    """At least min_match, no more than one of any letter"""
    c = 0
    count = Counter(word)
    for letter in letters:
        char_count = count.get(letter, 0)
        if char_count > 1:
            return False
        elif char_count == 1:
            c += 1
        if c == min_match:
            return True
    return True

def find_words(srcfile, required=[], letters=[], min_match=3):
    required = set(required)
    words = (word for word in srcfile.split())
    words = (word for word in words if set(word).issuperset(required))
    words = (word for word in words if valid(word, letters, min_match))
    return words

```