# Comprehension filter excludes too much

Hello everybody,

I run into a problem and I don’t know if I’m doing something really wrong or if I don’t understand how the filters of list comprehensions work. I wrote the following code:

``````for x <- 0..2, y <- 0..2, do: {x,y}
``````

which creates the list:

``````[{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}]
``````

pretty good so far. But now I want to exclude the tuple {1,1} from it. So I wrote my code like this:

``````for x <- 0..2, y <- 0..2, (x != 1) && (y != 1), do: {x,y}
``````

but the generated list now excludes every tuple that contains a single 1.
EDIT: the above line is wrong, it obviously doesn’t exclude every tuple with a 1 in it, but tuple {1,2} is missing.
EDIT2: I copy pasted the wrong line, that’s why my list was wrong, actually every 1 is excluded. So Edit1 is wrong.

``````[{0, 0}, {0, 2}, {2, 0}, {2, 2}]
``````

Am I doing something horribly wrong?

Greetings,
eXodiquas

`(x != 1) && (y != 1)` is short circuting.

So once it sees something with `x=1`, it evaluates to `true`.

1 Like

I do not get the question. `x != 1 && y != 1` means neither equals `1`. Once any of them equals `1`, it gets filtered out. The boolean condition should be:

``````for x <- 0..2, y <- 0..2, !(x == 1 && y == 1), do: {x,y}
#⇒ [{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 2}, {2, 0}, {2, 1}, {2, 2}]

``````
3 Likes

Sorry guys, I got my boolean logic completly wrong.

It was a long day.

Thanks for the hints.

2 Likes

Why not just `{1, 1} == {x, y}`?

3 Likes

Or rather `!=` I’m guessing. ^.^

3 Likes

I never can’t remember if `true` means to keep or to reject a value…

1 Like

Think of it as `Enum.filter`, `true` keeps.

Which has a very similar problem to me… I often start with `Enum.reject/2` and inverted logic. After that works I just rename the function call and remove the `!/1`

1 Like

Heh, that’s fascinatingly different from most languages. Many languages don’t even have a `reject` equivalent, just a `filter`, I’m curious where you picked up that habit, what language? ^.^

GNU make… A co worker of mine was confused why there is a `filter-out` but no `filter-in`, and since we were discussing this after office hours with a beer in the hand (and 2 or 3 in mind), I ended up totally confused and since then I have problems to remember the direction of any `filter` function unless explicitely stated…

1 Like

Hmm? But in gnu make `filter` is the default filter function (which operates like `Enum.filter`), `filter-out` is the oddity inversed function.

If it helps, filtering in python comprehensions works the same as an in elixir/erlang too?

That’s why BuckleScript’s Belt library uses `keep` instead of `filter` - i.e. the predicate signals which data to “keep” in the output.

While `filter` is the established name it doesn’t really clarify the intent behind the predicate - though in common usage it’s a “passing filter”, rather than a “blocking filter”.

2 Likes

That sounds like in a mutating thought though. Filtering in math and signal processing is where the term `filter` comes from, which means to ‘filter’ the data through to get only the output that goes through the filter. So if you have working in the math/signal worlds then `filter` makes sense from that too.

1 Like