142

I want to compare 2 iterables and print the items which appear in both iterables.

>>> a = ('q', 'r')
>>> b = ('q')


# Iterate over a. If y not in b, print y.
# I want to see ['r'] printed.
>>> print([ y if y not in b for y in a])
                              ^

But it gives me a invalid syntax error where the ^ has been placed. What is wrong about this lamba function?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
OrangeTux
  • 11,142
  • 7
  • 48
  • 73

5 Answers5

254

You got the order wrong. The if should be after the for (unless it is in an if-else ternary operator)

[y for y in a if y not in b]

This would work however:

[y if y not in b else other_value for y in a]
pfnuesel
  • 14,093
  • 14
  • 58
  • 71
Volatility
  • 31,232
  • 10
  • 80
  • 89
  • Thanks. I saw this post http://stackoverflow.com/questions/4406389/if-else-in-a-list-comprehension about an if else statement in a lambda function. And I thought that using only the if statement (without the else) would work in the same order. – OrangeTux Mar 18 '13 at 10:51
51

You put the if at the end:

[y for y in a if y not in b]

List comprehensions are written in the same order as their nested full-specified counterparts, essentially the above statement translates to:

outputlist = []
for y in a:
    if y not in b:
        outputlist.append(y)

Your version tried to do this instead:

outputlist = []
if y not in b:
    for y in a:
        outputlist.append(y)

but a list comprehension must start with at least one outer loop.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
9

list comprehension formula:

[<value_when_condition_true> if <condition> else <value_when_condition_false> for value in list_name]

thus you can do it like this:

[y for y in a if y not in b]

Only for demonstration purpose : [y if y not in b else False for y in a ]

Vishvajit Pathak
  • 3,351
  • 1
  • 21
  • 16
  • 2
    You can't put an `else` in a list comprehension, not where you put one at least. Don't confuse a list comprehension (filtering), with a conditional expression (which must have a value, making the else expression mandatory). – Martijn Pieters Jun 20 '17 at 06:00
  • 1
    Agree. `else` be used in list comprehension though as shown in the code. – Vishvajit Pathak Jun 21 '17 at 11:43
  • 2
    That's a *conditional expression*. It can be used anywhere a valid expression is applicable. It has not specific to list comprehensions. – Martijn Pieters Jun 21 '17 at 11:45
5

This is not a lambda function. It is a list comprehension.

Just change the order:

[ y for y in a if y not in b]
eumiro
  • 207,213
  • 34
  • 299
  • 261
1

If you use sufficiently big list not in b clause will do a linear search for each of the item in a. Why not use set? Set takes iterable as parameter to create a new set object.

>>> a = ["a", "b", "c", "d", "e"]
>>> b = ["c", "d", "f", "g"]
>>> set(a).intersection(set(b))
{'c', 'd'}
artdanil
  • 4,952
  • 2
  • 32
  • 49