42

I'm getting started with Python and is currently learning about list comprehensions so this may sound really strange.

Question: Is it possible to use list comprehension to create a list of elements in t that is not found in s?

I tried the following and it gave me an error:

>>> t = [1, 2, 3, 4, 5]
>>> s = [1, 3, 5]
>>>[t for t not in s]

[t for t not in s]
           ^
SyntaxError: invalid syntax
Nyxynyx
  • 61,411
  • 155
  • 482
  • 830
  • A comprehension can only have two kinds of clauses: `for spam in eggs` and `if bacon`. If you can figure out how to write what you want in terms of a `for` loop or an `if` check, you're set. (In this case, you can.) If not, you either need to factor pieces out into functions, or write an explicit loop block statement instead of a comprehension. – abarnert Oct 22 '13 at 01:51

4 Answers4

71

Try this:

[x for x in t if x not in s]

You can nest any for if statements in list comprehensions. Try this identation, to get really long chains of conditionals, with a clearer intuition about what the code is doing.

my_list = [(x,a)
           for x in t
           if x not in s
           if x > 0
           for a in y
           ...]

See?

Lucas Ribeiro
  • 6,132
  • 2
  • 25
  • 28
6
[item  for item  in t if item not in s]
Leonardo.Z
  • 9,425
  • 3
  • 35
  • 38
2

I know you're asking about list comprehensions, but I wanted to point out that this specific problem would be better accomplished using sets. The result you want is the difference of set t and s:

>>> t = {1,2,3,4,5}
>>> s = {1,3,5}
>>>
>>> t - s
set([2, 4])
>>>
>>> t.difference(s)
set([2, 4])

Just hoping to expand your knowledge of the tools Python provides to you.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • 3
    This may not be useful if `t` needs to preserve order and any repeated elements... Also... only one needs to be a set here - possibly use the smaller to start with, eg: `set(s).symmetric_difference(t)` – Jon Clements Oct 22 '13 at 01:57
  • 2
    @JonClements Great insight. I appreciate the feedback. – Jonathon Reinhart Oct 22 '13 at 02:00
  • Indeed, only one needs to be a set: `"Note, the non-operator versions of union(), intersection(), difference(), and symmetric_difference(), issubset(), and issuperset() methods will accept any iterable as an argument. In contrast, their operator based counterparts require their arguments to be sets."` – Jonathon Reinhart Oct 22 '13 at 02:01
1

For better efficiency, use a set:

mySet = set(s)
result = [x for x in t if x not in mySet]

Testing membership of a set is done is O(1), but testing membership in a list is O(n).

MangoHands
  • 1,141
  • 9
  • 11