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)}