I have a list of tuples that I want to get all the combinations for as a set and filter out certain sets based on criteria.

For example

pairs = [(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)] combs = [] for i in range(len(pairs)): intermediate = (set(list(combinations(pairs, i)))) if ((2,3) and (2,2) and (3,2)) in intermediate: combs.append(intermediate)

But it doesn’t detect if any of the tuples are in the set, so I tried a more basic test version.

pairs = [(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)] test = set(combinations(pairs,1)) if (1,1) in test: print("true")

This also doesn’t work even though I can clearly see in my variable explorer that the set contains (1,1).

I’ve also tried adding an integer 1 as one of the elements in pairs and checking if 1 is in the set but that still doesn’t work. I’ve run out of ideas and some help would be appreciated.

## Answer

There are two issues here…

**First**, it would seem like you are not testing membership at the correct depth of a nested data structure. When you call `set(combinations(pairs, i))`

, you get a structure that is 3 levels deep: A `set`

of `tuples`

of `tuples`

of `ints`

(ints 3 containers deep).

>>> pairs = [(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)] >>> test = set(combinations(pairs,1)) >>> test {((3, 2),), ((2, 3),), ((1, 1),), ((2, 2),), ((3, 1),), ((1, 3),), ((1, 2),), ((3, 3),), ((2, 1),)}

It is perfectly valid to test if a specific `tuple`

of `tuples`

of `ints`

is contained within the `set`

, but those tuples aren’t automatically flattened for you to be able to test against a simple tuple of ints.

>>> ((1,1),) in test True >>> (1,1) in test False

If you want to check if any tuples within the set contain a specific sub-tuple, you’ll have to iterate over the set and check each top level tuple individually (hint: things like `map`

can make this iteration a little shorter and sweeter)

for top_tuple in test: if (1,1) in top_tuple: print("found it!")

**Second**, is a somewhat common trap for new python programmers, which is chaining logical operators. You must think of `and`

`or`

`in`

etc.. as similar to mathematical operators similar to `+`

`-`

`*`

`/`

etc.. The other important thing is how the logical operators treat things that aren’t `True`

and `False`

. In general python treats things that are empty such as empty lists, strings, tuples, sets, etc.. as `False`

, as well as things that are equal to `0`

. Basically everything else non-zero or non-empty is treated as `True`

. Then when you run into an `and`

, if the first value (on the left) is `True`

-ish the return value of the `and`

statement will be whatever is on the right. if The first value is `False`

-ish, the return value will be that first value. When you chain them together, they get evaluated left to right.

>>> (1,1) and "cookies" "cookies" >>> False and "cookies" False >>> (2,3) and (2,2) and (3,2) (3, 2)