How to check if string is a pangram?

pangram, python, python-2.7, string

Solution

is_pangram = lambda s: not set('abcdefghijklmnopqrstuvwxyz') - set(s.lower())

>>> is_pangram('abc')
False
>>> is_pangram('the quick brown fox jumps over the lazy dog')
True
>>> is_pangram('Does the quick brown fox jump over the lazy dog?')
True
>>> is_pangram('Do big jackdaws love my sphinx of quartz?')
True

Test string `s` is a pangram if we start with the alphabet, remove every letter found in the test string, and all the alphabet letters get removed.

Explanation

The use of 'lambda' is a way of creating a function, so it's a one line equivalent to writing a `def` like:

 def is_pangram(s):
     return not set('abcdefghijklmnopqrstuvwxyz') - set(s.lower())

`set()` creates a data structure which can't have any duplicates in it, and here:

- The first set is the (English) alphabet letters, in lowercase

- The second set is the characters from the test string, also in lowercase. And all the duplicates are gone as well.

Subtracting things like `set(..) - set(..)` returns the contents of the first set, minus the contents of the second set. `set('abcde') - set('ace') == set('bd')`.

In this pangram test:

- we take the characters in the test string away from the alphabet

- If there's nothing left, then the test string contained all the letters of the alphabet and must be a pangram.

If there's something leftover, then the test string did not contain all the alphabet letters, so it must not be a pangram.

any spaces, punctuation characters from the test string set were never in the alphabet set, so they don't matter.

`set(..) - set(..)` will return an empty set, or a set with content. If we force sets into the simplest True/False values in Python, then containers with content are 'True' and empty containers are 'False'.

So we're using `not` to check "is there anything leftover?" by forcing the result into a True/False value, depending on whether there's any leftovers or not.

`not` also changes True -> False, and False -> True. Which is useful here, because (alphabet used up) -> an empty set which is `False`, but we want `is_pangram` to return `True` in that case. And vice-versa, (alphabet has some leftovers) -> a set of letters which is `True`, but we want `is_pangram` to return `False` for that.

Then return that True/False result.

is_pangram = lambda s: not set('abcdefghijklmnopqrstuvwxyz') - set(s.lower())
#      Test string `s`
#is a pangram if
#                           the alphabet letters 
#                                                             minus 
#                                                               the test string letters
#                   has NO leftovers

Problem

I want to create a function which takes a string as input and check whether the string is pangram or not (pangram is a piece of text which contains every letter of the alphabet). I wrote the following code, which works, but I am looking for an alternative way to do it, hopefully a shorted way. ``` import string def is_pangram (gram): gram = gram.lower() gram_list_old = sorted([c for c in gram if c != ' ']) gram_list = [] for c in gram_list_old: if c not in gram_list: gram_list.append(c) if gram_list == list(string.ascii_lowercase): return True else: return False ``` I feel like this question might be against the rules of this website but hopefully it isn't. I am just curious and would like to see alternative ways to do this.

Original source