0

we know that | is used to combine two dictionaries, like,

dct_1 = {'a': 1}
dct_2 = {'b': 2}
print(dct_1 | dct_2)

gives,

{'a': 1, 'b': 2}

but if one wants to use the same | in match-case to combine two dictionaries,

x = {'a': 1, 'b': 2}
d = {'a': 1}
c = {'b': 2}
match x:
  case d | c: print(x)

gives error,

SyntaxError: name capture 'd' makes remaining patterns unreachable

as they have made | equivalent to or in match-case. similarly,

match x:
  case ({**d} | {**c}): print(x)

gives,

SyntaxError: alternative patterns bind different names

similarly,

match x:
  case (d | {**c}): print(x)

gives,

SyntaxError: alternative patterns bind different names

and,

match x:
  case ({**d} | c): print(x)

gives,

SyntaxError: alternative patterns bind different names

how do I use | to combine two dictionaries in a case statement?

apostofes
  • 2,959
  • 5
  • 16
  • 31
  • 2
    What are you expecting the result to be when you combine dictionaries in `case`? Are you sure it even makes sense? – Barmar May 03 '22 at 18:27
  • that ‘|’ works like it does to combine two dictionaries, and we get ‘x’ matches with the combined dictionary – apostofes May 03 '22 at 19:05
  • But the case argument is a pattern, not a value. What is the pattern you're trying to match when you combine two dictionaries? – Barmar May 03 '22 at 19:09
  • Any dictionary which contains ‘{‘a’: 1, ‘b’: 2}’ should match with ‘case d | c’. a dictionary like {‘a’: 1, ‘b’: 2, ‘e’: 1} should match. – apostofes May 03 '22 at 19:15
  • What if there are conflicting keys in the two dictionaries? – Barmar May 03 '22 at 19:17
  • what does conflicting keys mean, I do not know, does it mean like this, `x = {'a': 1, 'b': 2, 'a': 5}`. the documentation says something like this, `If duplicate keys are detected in the mapping pattern, the pattern is considered invalid. A SyntaxError is raised for duplicate literal values; or a ValueError for named keys of the same value.` – apostofes May 03 '22 at 19:23
  • I mean `x = {'a': 1, 'b: 2'} y = {'a': 3}` – Barmar May 03 '22 at 19:25
  • I expect the `|` to work as it does for standard dictionaries, in the above scenario, `x | y` would give `{'a': 3, 'b': 2}`, and `case x | y` should match with any dictionary containing `{'a': 3, 'b': 2}` but instead it raises error as I described in the post. – apostofes May 03 '22 at 19:28
  • All other uses of `|` in cases means "or", so doing it differently for dictionaries would be inconsistent. – Barmar May 03 '22 at 19:45

1 Answers1

0

it appears that the case statement does not care about the assignments,

dct_1 = {'a': 1}
dct_2 = {'b': 2}

if we do,

dct = {'a': 1, 'b': 2}
dct_1 = {'a': 1}
dct_2 = {'b': 2}
match dct:
  case {'a': 1} | {'b': 2}: 
    print("using {'a': 1} | {'b': 2}", dct)

then it outputs,

using {'a': 1} | {'b': 2} {'a': 1, 'b': 2}

so, probably there is nothing wrong with the use of | for dictionaries.

similar situation could be seen here,

dct = {'a': 1, 'b': 2}
eee = '1'
match dct:
  case eee: print("using eee", dct)

which outputs,

using eee {'a': 1, 'b': 2}

here, again case does not care about the assignment,

eee = '1'

and,

case eee:

is more like a wildcard pattern matching

if I do something like this, (using '1' instead of eee in case statement)

dct = {'a': 1, 'b': 2}
eee = '1'
match dct:
  case '1': print("using '1'", dct)

then it would attempt at matching the dictionary dct with '1' and it fails (as expected), so, there is no output.

apostofes
  • 2,959
  • 5
  • 16
  • 31
  • 1
    The logic is not "does not care about the assignments". The logic is "creates a local variable to hold the matched result" instead. If you write your example as `case eee: print(eee)` you will see `eee` is created here to hold the matched `{'a': 1, 'b': 2}`. As you mentioned "a wildcard pattern matching". Yes, it is. – John Lin Feb 24 '23 at 08:40
  • The we can come to a conclusion that patterns are literally composed by constants, and cannot be passed in from outer variables, because any variables inside patterns are treated as result-holding variables. – John Lin Feb 24 '23 at 08:57