As part of a larger problem, I am trying to write a function that uses pattern matching in order to extract fields from a given dictionary.
For example, given a dictionary like:
example = {
'want1': [1, 2, 3],
'want2': ['a', 'b', 'c'],
'want3': [1.1, 2.2, 3.3],
'want4': 'hello',
}
I want to write a function that retrieves the value there if it exists, makes sure it is a list and return it.
Something like:
extract('want1', example) # [1, 2, 3]
extract('want2', example) # ['a', 'b', 'c']
extract('want4', example) # None
extract('want5', example) # None
While this problem isn't that difficult, as a learning process I am looking into structural pattern matching and I came up with the following (wrong) solution:
def extract(field, data):
match data:
case {field: list() as values}:
return values
This function has a syntax error because of the field variable as a key in the pattern.
Looking further into it I found out that keys in patterns can only be literals or attribute lookups.
Based on this, I then tried to hack the following:
from types import SimpleNamespace
def extract(field, data):
lookup = SimpleNamespace(field=field)
match data:
case { lookup.field: list() as values}:
return values
and strangely enough this works.
My feeling is that the above is a hack to get around something that was specifically avoided for a reason. If this works then why does a variable as a key not work?
Also, would there be a better way of doing this?
I could do this without pattern matching, but I feel that it offers quite some benefits in not having to explicitly check that the value exists in the dictionary and also not having to explicitly check that the value is a list.
This is a really bad example usage of pattern matching. This can be solved by a much simpler function:
Outputs (for both functions):