user3342816
user3342816

Reputation: 1263

Check that combinations not in list

Simplified – have a dict:

flags = { 'a': 0, 'b': 1, 'c': 1, 'd': 0, 'e': 1, 'f': 1 }

Now there are certain combinations that are not allowed:

no_combo = [
    ['a', 'c'],
    ['b', 'd', 'e']
]

How best to validate I do not have combinations in flags that are not allowed according to no_combo?

From example above we have a conflict because both b and e are set to 1.

set_flags = [k for k in flags if flags[k]]

gives:

['b', 'c', 'e', 'f']

which is in conflict with restriction of no combinations of no_combo[1]:

['b', 'd', 'e']

Now to cross check with no_combo?

I have this:

for combo in no_combo:
    if len([f for f in combo if f in set_flags]) > 1:
        print('fail on', combo)

But wondering if there is a better way to solve it?

Is there for example some similar method to all() and any() for this purpose?

Upvotes: 0

Views: 41

Answers (1)

Dani Mesejo
Dani Mesejo

Reputation: 61930

You could use sum:

flags = {'a': 0, 'b': 1, 'c': 1, 'd': 0, 'e': 1, 'f': 1}

no_combo = [
    ['a', 'c'],
    ['b', 'd', 'e']
]

for combo in no_combo:
    if sum(flags.get(c, 0) for c in combo) > 1:
        print('fail on', combo)

Output

fail on ['b', 'd', 'e']

This saves you the list creation (the one you use in the call to len). Note that this assumes the values of the flags are 0 or 1.

You could also use a while loop and break it as soon as the sum reaches 2. For example:

for combo in no_combo:
    total = 0
    for c in combo:
        total += flags.get(c, 0)
        if total > 1:
            print('fail on', combo)
            break

It is a little bit cumbersome but avoids iterating over the whole list, so it saves you some time.

Upvotes: 2

Related Questions