Lists may contain an arbitrary number of elements. There is no way to individually match all of the elements in a list in a case.
You can match all of the elements and then put a guard on the case.
match mylist:
case [*all_elements] if 'hi' in all_elements:
...
This doesn't seem much better than:
if 'hi' in mylist:
...
But let's say you want to determine if list has 'hi' as the first element and includes it again?
match mylist:
case ['hi', *other_elements] if 'hi' in other_elements:
...
Answer from Chris on Stack OverflowVideos
Lists may contain an arbitrary number of elements. There is no way to individually match all of the elements in a list in a case.
You can match all of the elements and then put a guard on the case.
match mylist:
case [*all_elements] if 'hi' in all_elements:
...
This doesn't seem much better than:
if 'hi' in mylist:
...
But let's say you want to determine if list has 'hi' as the first element and includes it again?
match mylist:
case ['hi', *other_elements] if 'hi' in other_elements:
...
Using match/case is not the most appropriate way to determine if a list contains some particular value. However, to answer the question then:
mylist= ["hello", "hi", 123, True]
for element in mylist:
match element:
case 'hello':
print('hello detected')
case 'hi':
print('hi detected')
Is there a way to match a value against a list of values? I'm trying to do something like this without using a bunch of ifs, but I can't figure out how.
animal = 'dog'
match animal:
case ['dog', 'cat', 'pig']:
print('Mammal!')
case ['crocodile', 'turtle']:
print('Reptile!')
case _:
print('I dont know')I’ve posted this on stackoverflow as well but I wanted to ask here as well.
Does looping within a match-case not work? I can loop outside of the match-case as many times as I want but once inside the case, it only iterates once.
Does this not work and is there a reason for doing so, or a way to accomplish this?
Thanks!
Link to stackoverflow
edit: I found out my issue comes from a try statement at the bottom of a case that wasn’t commented out. Did that and it fixed the whole problem. I feel so dumb.
cases accept a "guard" clause, which you can use for this purpose:
match x:
case w if w in a:
return "132"
case w if w in b:
return "564"
case w if w in c:
return "798"
the w here actually captures the value of x, part of the syntax here too, but it's more useful in some other fancy cases listed on the linked whatsnew page.
In this example, it's simpler to use good ol' if-elif.
if x in a:
return "132"
elif x in b:
return "564"
elif x in c:
return "798"
If you don't want to repeat the variable name, you can use a loop:
for lst, retval in [
(a, "132"),
(b, "564"),
(c, "798"),
]:
if x in lst:
return retval
Note: This is very similar to my answer on "Is there a way to match inequalities in Python ≥ 3.10?".
Now, it would be different if you were doing any actual structural pattern matching, which is what match-case is intended for. Then you might want to use a guard clause like in tevemadar's answer. Say for example x is a structure:
match x:
case (w,) if w in a:
return "132"
case (_, w) if w in b:
return "564"
case (_, _, w) if w in c:
return "798"
You can do this without match-case, but it's not as elegant:
for n, lst, retval in [
(1, a, "132"),
(2, b, "564"),
(3, c, "798"),
]:
if len(x) == n and x[-1] in lst:
return retval