1

Assume I got two pyomo sets A & B, which are containing following elements:

m.A = {1,2,3,4,5}
m.B = {a,b,c,d,5}

I want to check; if A has some elements which are also in B:

EDIT:

Well following does not work:

if m.A & m.B is not None:
    raise ValueError

At least for my case when m.A = [None] and m.B = ['some_string'], if-statement is also triggered, but bool(m.A & m.B) is working.

oakca
  • 1,408
  • 1
  • 18
  • 40
  • 1
    `if a & b` is what you want – user3483203 Aug 02 '18 at 13:21
  • 1
    will the intersection of these two sets work for you? "m.A & m.B" would give you elements which exist in both sets... – npobedina Aug 02 '18 at 13:21
  • @npobedina I think you are right something like `if m.A & m.B == None:` would work. – oakca Aug 02 '18 at 13:22
  • The post https://stackoverflow.com/q/3170055/5270581 already answers your question. – Laurent H. Aug 02 '18 at 13:23
  • Dupe starts with lists, not sets, but the answers are what you need. – user3483203 Aug 02 '18 at 13:24
  • @Icedkk if you need to raise an alert if there are common entries, then it's rather "if m.A & m.B => raise alert" – npobedina Aug 02 '18 at 13:24
  • There is a bit of nuance here that makes this question similar, but not an exact duplicate of the usual Python question. The `Set` objects above are from the `Pyomo` algebraic modeling/optimization library, not standard python `set`, but due to duck typing, the behavior is the same in this instance. The usual `&` vs. `.intersection()` comparisons may not apply here. – Qi Chen Aug 02 '18 at 14:05
  • @QiChen true. The odd behavior is that when I create the intersection of two sets via `m.A & m.B`, a virtual set is created without an element (it says `Virtual`, where usually the elements stay.) And this virtual set is triggering `if m.A & m.B is not None`. – oakca Aug 03 '18 at 15:06
  • This is lazy evaluation in action. The intersection set is not actually evaluated until it is used, so you are given a virtual set object back as a placeholder. – Qi Chen Aug 03 '18 at 15:10

2 Answers2

5

The most compact way you could achieve this is by using the & operator:

a = {1,2,3,4}
b = {4,5,6}
result = bool(a & b)

Speed comparison

Using the & operator:

%timeit bool(a & b)
297 ns ± 3.04 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Using the intersection method:

%timeit bool(a.intersection(b))
365 ns ± 27.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

The two solution are pretty similar, the second one most probably faces overhead from the method call.

Luca Cappelletti
  • 2,485
  • 20
  • 35
  • Well I ll try both, the only problem might me: they are no ordinary python lists therefore I am not sure if .intersection would work. or bool(). I ll try then update here. – oakca Aug 02 '18 at 13:27
  • 1
    These are method applied to sets, not lists. Bool casts the result to boolean, as it returns `False` for empty set `{}` and true for a non empty set `{something}`. – Luca Cappelletti Aug 02 '18 at 13:28
0

You are looking for intersection:

>>> A = {1,2,3,4,5}
>>> B = {'a','b','c','d',5}
>>> A.intersection(B)
set([5])
Maurice Meyer
  • 17,279
  • 4
  • 30
  • 47