Rajib Lochan Sarkar
Rajib Lochan Sarkar

Reputation: 167

Search part of tuple list

I am trying to do a list comprehension of a tuples list based on another list of tuples with partial match.

x = [((1,1),(1,1),(1,2)),
     ((2,1),(1,3),(2,9)),
     ((2,1),(2,3),(2,9))]
y = [(2,1),(1,3)]
[i for i in x for k in y if k in i]

e.g. in this x is a list of tuples & y is the desired list of tuples. If y is found in any of the items in the list of tuples in x, it should return that item.

Result is: [((2, 1), (1, 3), (2, 9)), ((2, 1), (1, 3), (2, 9)), ((2, 1), (2, 3), (2, 9))]

But I want only : [((2, 1), (1, 3), (2, 9))]

I tried with single tuple & it gave the desired result. But not sure why it doesn't work when I pass a tuple list.

x = [((1,1),(1,1),(1,2)),
     ((2,1),(1,3),(2,9)),
     ((2,1),(2,3),(2,9))]
y = (2,1)
[i for i in x if y in i]

Result: [((2, 1), (1, 3), (2, 9)), ((2, 1), (2, 3), (2, 9))]

Upvotes: 3

Views: 77

Answers (3)

S.B
S.B

Reputation: 16526

You can use:

x = [
    ((1, 1), (1, 1), (1, 2)),
    ((2, 1), (1, 3), (2, 9)),
    ((2, 1), (2, 3), (2, 9)),
]
y = [(2, 1), (1, 3)]

print([t for t in x if not set(y).difference(t)])

output:

[((2, 1), (1, 3), (2, 9))]

If you subtract tuples inside x from y with set operations, if all the sub tuples are present, you'll end up with an empty set, so you want that tuple.

You could also write if set(y).issubset(t) instead of if not set(y).difference(t) part.(borrowed from @kellyBundy's answer)

What if I want any tpl of y to be true but not all.

print([t for t in x if set(y).intersection(t)])

Upvotes: 1

Kelly Bundy
Kelly Bundy

Reputation: 27629

If it doesn't have to be a comprehension:

[*filter({*y}.issubset, x)]

Upvotes: 3

Chris
Chris

Reputation: 36611

all is the ticket here, determining if all tuples in y are in each element in x.

[
  tpl 
  for tpl in x 
  if all(tpl2 in tpl 
         for tpl2 in y)
]
# [((2, 1), (1, 3), (2, 9))]

Upvotes: 2

Related Questions