Pattern Matching
Ekkart Kleinod
•
Auf dieser Seite
Hier in die Doku schauen, wie _
, *
und **
noch zum Vorteil eingesetzt werden können
Einfaches Matching
def handle_command(self, message): match message: case ['BEEPER', frequency, times]: self.beep(times, frequency) case ['NECK', angle]: self.rotate_neck(angle) case ['LED', ident, intensity]: self.leds[ident].set_brightness(ident, intensity) case ['LED', ident, red, green, blue]: self.leds[ident].set_color(ident, red, green, blue) case _: raise InvalidCommand(message)
Matching mit _
metro_areas = [ ('Tokyo', 'JP', 36.933, (35.689722, 139.691667)), ('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)), ('Mexico City', 'MX', 20.142, (19.433333, -99.133333)), ('New York-Newark', 'US', 20.104, (40.808611, -74.020386)), ('São Paulo', 'BR', 19.649, (-23.547778, -46.635833)), ] print(f'{"":15} | {"latitude":>9} | {"longitude":>9}') for record in metro_areas: match record: case [name, _, _, (lat, lon)] if lon <= 0: print(f'{name:15} | {lat:9.4f} | {lon:9.4f}')
| latitude | longitude
Mexico City | 19.4333 | -99.1333
New York-Newark | 40.8086 | -74.0204
São Paulo | -23.5478 | -46.6358
Matching mit Mappings
from collections import OrderedDict def get_creators(record: dict) -> list: match record: case {'type': 'book', 'api': 2, 'authors': [*names]}: return names case {'type': 'book', 'api': 1, 'author': name}: return [name] case {'type': 'book'}: raise ValueError(f"Invalid 'book' record: {record!r}") case {'type': 'movie', 'director': name}: return [name] case _: raise ValueError(f'Invalid record: {record!r}') print(get_creators(dict(api=1, author='Douglas Hofstadter', type='book', title='Gödel, Escher, Bach'))) print(get_creators(OrderedDict(api=2, type='book', title='Python in a Nutshell', authors='Martelli Ravenscroft Holden'.split()))) print(get_creators({'type': 'book', 'pages': 770})) print(get_creators('Spam, spam, spam'))
['Douglas Hofstadter']
['Martelli', 'Ravenscroft', 'Holden']
ValueError: Invalid 'book' record: {'type': 'book', 'pages': 770}
ValueError: Invalid record: 'Spam, spam, spam'
Matching mit Rest-Capture
creator = dict(author='Douglas Hofstadter', type='book', title='Gödel, Escher, Bach') match creator: case {'type': 'book', **details}: print(f"Book details: {details}")
Book details: {'author': 'Douglas Hofstadter', 'title': 'Gödel, Escher, Bach'}