Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic self-referencing conditional in list comprehension

Goal: Create a conditional statement in a list comprehension that (1) dynamically tests -- i.e., upon each iteration -- if the element is not in the list being comprehended given (2) the list is itself updated on each iteration.

Background code:

arr = [2, 2, 4]
l = list()

Desired output:

l = [2, 4]

Desired behavior via for loop:

for element in arr:
        if element not in l:
            l.append(element)

Incorrect list comprehension not generating desired behavior:

l = [element for element in arr if element not in l]

Question restated: How do I fix the list comprehension so that it generates the desired behavior, i.e., the desired output stated above?

like image 423
va01 Avatar asked Mar 30 '16 15:03

va01


1 Answers

If you absolutely must use a list comprehesion, you can just recast your for loop into one. The downside is that you will end up with a list of None elements, since that is what list.append returns:

>>> arr = [2, 2, 4]
>>> l = list()
>>> _ = [l.append(element) for element in arr if element not in l]
>>> print(l)
[2, 4]
>>> print(_)
[None, None]

If you are tied to comprehensions, but not necessarily to list comprehensions, you can use the generator comprehension suggested by @tdelaney. This will not create any unwanted byproducts and will do exactly what you want.

>>> arr = [2, 2, 4]
>>> l = list()
>>> l.extend(element for element in arr if element not in l)

A better way than either would probably be to put the original list into a set and then back into a list. The advantage of using a set to extending a list is that sets are much faster at adding elements after checking for prior containment. A list has to do a linear search and reallocate every time you add an element.

>>> l = list(set(arr))
like image 91
Mad Physicist Avatar answered Oct 22 '22 00:10

Mad Physicist