Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3.10 pattern matching (PEP 634) - wildcard in string

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.

like image 395
Martin Schroter Avatar asked Nov 25 '21 12:11

Martin Schroter


People also ask

Does Python 3.9 have match?

As of early 2021, the match keyword does not exist in the released Python versions <= 3.9. Since Python doesn't have any functionality similar to switch/case in other languages, you'd typically use nested if/elif/else statements or a dictionary.

Does Python have pattern matching?

'Structural Pattern Matching' was newly introduced in Python 3.10. The syntax for this new feature was proposed in PEP 622 in JUne 2020. The pattern matching statement of Python was inspired by similar syntax found in Scala, Erlang, and other languages.

What are the new features added in the latest version of Python 3.10 2?

Summary – Release highlights New syntax features: PEP 634, Structural Pattern Matching: Specification. PEP 635, Structural Pattern Matching: Motivation and Rationale. PEP 636, Structural Pattern Matching: Tutorial.

How do you use wildcards in sequence patterns?

Sequence patterns support wildcards: [x, y, *rest] and (x, y, *rest) work similar to wildcards in unpacking assignments. The name after * may also be _, so (x, y, *_) matches a sequence of at least two items without binding the remaining items.

What is this Pep 634?

This PEP is a tutorial for the pattern matching introduced by PEP 634. PEP 622 proposed syntax for pattern matching, which received detailed discussion both from the community and the Steering Council. A frequent concern was about how easy it would be to explain (and learn) this feature.

What is pattern matching in Python?

Patterns consist of sequences, mappings, primitive data types as well as class instances. Pattern matching enables programs to extract information from complex data types, branch on the structure of data, and apply specific actions based on different forms of data.

What is the difference between Python structural pattern matching and other languages?

@lsabi My understanding is that other languages mainly have switch-case structure, which is a fancy if-else. But what python's structural pattern matching is offering is far more powerful, it allows you to select a branch of code based on the structure of the object you're comparing.


Video Answer


1 Answers

You can use a guard:

for event in data:
    match event:
        case {'id': x} if x.startswith("matchme"): # guard
            print(event["message"])
        case {'id':'anotherid'}:
            print(event["message"])

Quoting from the official 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.")

See also:

  • PEP 622 - Guards
  • PEP 636 - Adding conditions to patterns
  • PEP 634 - Guards
like image 176
Abdul Niyas P M Avatar answered Nov 15 '22 20:11

Abdul Niyas P M