I know there are other ways to check if dict is empty or not using match/case (for example, dict(data) if len(data) == 0), but I can't understand why python give different answers for list and dict types while we check for emptiness
data = [1, 2]
match data:
case []:
print("empty")
case [1, 2]:
print("1, 2")
case _:
print("other")
# 1, 2
data = {1: 1, 2: 2}
match data:
case {}:
print("empty")
case {1: 1, 2: 2}:
print("1, 2")
case _:
print("other")
# empty
There are different patterns used on the match case Python implementation. When a list or tuple is used, the pattern used is the one called Sequence Patterns. Here's an example found on the PEP:
match collection:
case 1, [x, *others]:
print("Got 1 and a nested sequence")
case (1, x):
print(f"Got 1 and {x}")
So let's say that we set collection as [1, 2]
The output will be:
Got 1 and 2
If we set is as [1, [2, 3]] the output will be:
Got 1 and a nested sequence
This happens because the Sequence Pattern, tries to match a given sequence on the list. So in the case you passed, it is going to try to match exactly [1, 2].
On the other hand, when a dict is used, the Mapping Patterns is the rule. If you execute this code, you will understand better.
config1 = {"router": "CNC", "network": "lan"}
config2 = {"router": "MAC"}
config3 = {"router": None}
config4 = {"network": "lan"}
configs = [config1, config2, config3, config4]
for config in configs:
match config:
case {"router": "MAC"}:
print("Configuring MAC router")
case {"router": "CNC"}:
print("Configuring CNC router")
case {"router": None} | {}:
print("No router available, please check config again")
The output is going to be this:
Configuring CNC router
Configuring MAC router
No router avaiable, please cheg config again
No router avaiable, please cheg config again
So, as you can see, the code actually does not compare using == or is is actually only look on the configs, by the keys defined on the case.
So if all the keys and values for the case dict can be found on the config dict, they are going to enter on that case. This happens because the idea is that you do not wanna compare the dict object itself, but check if some keys are matching with what you expecte to execute a certain action.
Basically all the keys that are present on the config dict but are not on the cases dicts is going to be ignored (not relevant for the match case)
When you put a case with an empty dict, you have no key, values, so any dict passed on the match will be accepted.
More information about this subject can be found on the official PEP:
https://peps.python.org/pep-0622/#sequence-patterns
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With