Can this for loop code(with an `if not in` condition) be converted to list comprehension?

Viewed 74

How can this code be converted to a list comprehension?

pangram = "The quick brown fox jumps over the lazy dog"
lst = []
for char in pangram.casefold():
    if char not in lst:
        lst.append(char)
lst.sort()
print(''.join(lst))

I tried the following list comprehension but it is not working:

lst = [char for char in pangram.casefold if char not in lst]

It gives the following error

NameError: name 'lst' is not defined

Please suggest a solution.

3 Answers

It's possible to hack it with a list comprehension but you'll have to pre-define lst first:

In [1]: pangram = "The quick brown fox jumps over the lazy dog"                                                         
In [2]: lst = []                                                                                                        
In [3]: [lst.append(char) for char in pangram.casefold() if char not in lst] 
In [5]: lst.sort()                                                                                                      
In [6]: print(''.join(lst))                                                                                             
 abcdefghijklmnopqrstuvwxyz

But, this is really NOT a good practice because list comprehensions are meant for creating lists, not for mutating an existing one. In this solution, you are actually creating a list of None's because .append() returns None.

If the goal is just to get the unique values and order is not important, use a set instead. (I assume order is not important because you sort it after).

In [29]: pangram = "aAaabBBbbcCc"                                                                                       

In [30]: lst = list(set(pangram.casefold()))                                                                            
In [31]: lst.sort()                                                                                                     
In [32]: print(''.join(lst))                                                                                            
abc

In [33]: lst = []                                                                                                       
In [34]: [lst.append(char) for char in pangram.casefold() if char not in lst]                                           
Out[34]: [None, None, None]
In [35]: lst.sort()                                                                                                     
In [36]: print(''.join(lst))                                                                                            
abc

There is no need for either a list or a comprehension. Use a set to automatically eliminate duplicates.

>>> pangram = "The quick brown fox jumps over the lazy dog"
>>> letters = set(pangram.casefold())  # the unique letters in pangram
>>> ''.join(sorted(letters))
' abcdefghijklmnopqrstuvwxyz'

In principle, the for loop can be converted to a list comprehension. This works by using a second set or list and exploiting that lst.append/set.add returns None, which allows evaluating a second expression when used with or.

>>> pangram = "The quick brown fox jumps over the lazy dog"
>>> seen = set()
>>> lst = [seen.add(char) or char for char in pangram.casefold() if char not in seen]
>>> lst.sort()
>>> ' abcdefghijklmnopqrstuvwxyz'

One liner could be:

"".join([letter for letter in sorted(set(pangram.casefold()))])

Related