Home > Software design >  Is there a better way to use multiple OR in dict comprehension?
Is there a better way to use multiple OR in dict comprehension?

Time:05-27

x = {'a': (2, 3), 'b': (4, 1), 'c': (3, 2), 'd': (1, 0), 'e': (2, 0)} 
x = {
    k: v
    for k, v in x.items()
    if (v[0] >= 2 and v[1] >= 0) or (v[0] >= 1 and v[1] > 1)
}
print(x)

In the 'if' block, I have a lot of logical 'or' enclosed with parenthesis. Is there better way to express it in dict comprehension?

Also, I can omit the () in the 'if' statement to make it more consise. Right?

CodePudding user response:

You can unpack the tuple. Keep the parentheses; and technically has a higher precedence than or, but not everyone knows that and this makes it more readable:

x = {k: (fst, snd) for k, (fst, snd) in x.items() if (fst >= 2 and snd >= 0) or (fst >= 1 and snd > 1)}

This outputs:

{'a': (2, 3), 'b': (4, 1), 'c': (3, 2), 'e': (2, 0)}

CodePudding user response:

In the 'if' block, I have a lot of logical 'or' enclosed with parenthesis. Is there better way to express it in dict comprehension?

No. Your both "main" conditions have one constraint that is a superset of the same constraint of the other side, and one that is incompatible.

Three boolean operators is the minimum you can do.

CodePudding user response:

One option is to write a function that checks for whether or not you want to include the item:

def my_filter(tup):
    return (tup[0] >= 2 and tup[1] >= 0) or (tup[0] >= 1 and tup[1] > 1)

x = {'a': (2, 3), 'b': (4, 1), 'c': (3, 2), 'd': (1, 0), 'e': (2, 0)} 
y = {
    k: v
    for k, v in x.items()
    if my_filter(v)
}
print(y)

Or you could wrap both conditions with any:

z = {
    k: v
    for k, v in x.items()
    if any(
        [v[0] >= 2 and v[1] >= 0,
         v[0] >= 1 and v[1] > 1]
    )
}
print(z)

Both of these will output:

{'a': (2, 3), 'b': (4, 1), 'c': (3, 2), 'e': (2, 0)}

TIO

  • Related