I got a large list of JSON objects that I want to parse depending on the start of one of the keys, and just wildcard the rest. A lot of the keys are similar, like "matchme-foo"
and "matchme-bar"
. There is a builtin wildcard, but it is only used for whole values, kinda like an else
.
I might be overlooking something but I can't find a solution anywhere in the proposal:
https://docs.python.org/3/whatsnew/3.10.html#pep-634-structural-pattern-matching
Also a bit more about it in PEP-636:
https://www.python.org/dev/peps/pep-0636/#going-to-the-cloud-mappings
My data looks like this:
data = [{
"id" : "matchme-foo",
"message": "hallo this is a message",
},{
"id" : "matchme-bar",
"message": "goodbye",
},{
"id" : "anotherid",
"message": "completely diffrent event"
}, ...]
I want to do something that can match the id without having to make a long list of |
's.
Something like this:
for event in data:
match event:
case {'id':'matchme-*'}: # Match all 'matchme-' no matter what comes next
log.INFO(event['message'])
case {'id':'anotherid'}:
log.ERROR(event['message'])
It's a relatively new addition to Python so there aren't many guides on how to use it yet.
CodePudding user response:
You can use a guard:
for event in data:
match event:
case {'id': x} if x.startswith("matchme"):
print(event["message"])
case {'id':'anotherid'}:
print(event["message"])
Quoting from the documentation,
Guard
We can add an if clause to a pattern, known as a “guard”. If the guard is false, match goes on to try the next case block. Note that value capture happens before the guard is evaluated:
match point: case Point(x, y) if x == y: print(f"The point is located on the diagonal Y=X at {x}.") case Point(x, y): print(f"Point is not on the diagonal.")