Search code examples
pythonlist-comprehension

Using a list comprehension with "if" to create a list of items without duplication


I have a list word_list = ['cat', 'dog', 'rabbit']. I want to use list comprehension to print each individual character from the list but removes any duplicate character. This is my code:

word_list = ['cat', 'dog', 'rabbit']
letter_list = [""]
letter_list = [letter for word in word_list for letter in word if letter not in letter_list ]
print(letter_list)

this returns ['c', 'a', 't', 'd', 'o', 'g', 'r', 'a', 'b', 'b', 'i', 't'] which is not the desired result ['c', 'a', 't', 'd', 'o', 'g', 'r', 'b', 'i'] and I can't figure out why.


Solution

  • It is technically possible to implement deduplication with a list comprehension if initialization of some variables are allowed.

    You can use a set seen to keep track of letters already encountered, and a set include to record whether the current letter was already seen before it is added to the set seen:

    seen = set()
    include = set()
    print([
        letter for word in word_list for letter in word
        if (
            include.clear() if letter in seen else include.add(1),
            seen.add(letter)
        ) and include
    ])
    

    Since Python 3.8 you can also use an assignment expression to avoid having to rely on side effects of functions, which are generally discouraged in a list comprehension:

    seen = set()
    print([
        letter for word in word_list for letter in word
        if (
            include := letter not in seen,
            seen := seen | {letter}
        ) and include
    ])
    

    But if you are not dead set on implementing the deduplication with a list comprehension, it would be cleaner to use the dict.fromkeys method instead since dict keys are always unique and follow insertion order since Python 3.7:

    from itertools import chain
    print([*{}.fromkeys(chain(*word_list))])
    

    Demo: Try it online!