Reputation: 37
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.
Upvotes: 0
Views: 889
Reputation: 11075
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)
Upvotes: 1
Reputation: 5489
Here is your test set, which does not contain (1,1) as an isolated tuple. It is a tuple inside a tuple.
{((3, 2),), ((2, 3),), ((1, 1),), ((2, 2),), ((3, 1),), ((1, 3),), ((1, 2),), ((3, 3),), ((2, 1),)}
To detect it, you can:
for combo in test:
if (1,1) in combo:
print("true")
#output: true
Upvotes: 1