I have a function that I want to do/output something different depending on what inputs I give it. I've made something useful with if else
logic but not elegant and I suspect there might be a shorter/more elegant way of doing it. What are the alternatives to the if else
on None
methods I've made?
e.g.,
def foo (a=None, b=None, c=None):
if a is None:
raise ValueError("a cannot be None!")
elif all([b is None, c is None]):
x = operations
return x
elif c is None:
x = operations
y = operations
return x, y
elif b is None:
x = operations
z = operations
return x, z
elif all([b is not None, c is not None]):
x = operations
y = operations
z = operations
return x, y, z
CodePudding user response:
If you have Python 3.10 installed you can use the match-case. Please refer to PEP 634
Honestly code readability is very subjective, if you were looking for something like a switch-case logic in python, Your code would look like -
def foo (a=None, b=None, c=None):
match a, b, c:
# Add all your cases
case None, None, _:
# Do Your Operations and Return
return
case other:
print("Other Cases")
This is one of the best features that got released with 3.10. Hope this helps you.
CodePudding user response:
If I understand your problem, you might find the new pattern matching syntax to be what you want (requires python >= 3.10
, spec in PEP634, tutorial in PEP636).
def foo(a=None, b=None, c=None):
match a, b, c:
case a_, None, None:
r = 1 * a_
case None, b_, None:
r = 2 * b_
# add more patterns here
case _:
r = None
return r
foo(a=1) # 1
foo(b=5) # 10
foo(a=0, b=0) # None # no pattern for a and b
foo(c=8) # None # no pattern for c
NB. the same is achievable with if/elif/else.
def bar(a=None, b=None, c=None):
if a is not None and b is None and c is None:
r = 1 * a
elif a is None and b is not None and c is None:
r = 2 * b
# add more elifs here
else:
r = None
return r
CodePudding user response:
It depends on what exactly you mean by "better" and what you are trying to do inside your ifs and elifs but I myself am not a big fan of the code style in your example either. I can become hard to read and maintain.
There are languages that make this kind of thing easy, but unfortunately Python is not one of them. However, there are a few ways that I think are "better", depending on what you are trying to do.
- Lots of elifs:
def show_food_description(food):
if food == "apple":
print("It's red and sweet")
elif food == "banana":
print("It's long and yellow")
elif food == "kiwi":
print("It's green and hairy")
else:
print("This food is unknown")
alternative:
def show_food_description(food):
descriptions = {
"apple": "It's red and sweet",
"banana": "It's long and yellow",
"kiwi": "It's green and hairy"
}
print(descriptions.get(food, "This food is unknown"))
- Testing for equality with more than one value:
food = "apple"
if food == "apple" or food == "banana" or food == "kiwi":
print("It's a fruit!")
alternative:
food = "apple"
fruits = ["apple", "banana", "kiwi"]
if food in fruits:
print("It's a fruit!")
- Execute different function
def add_one(x):
return x 1
def add_two(x):
return x 2
def add_three(x):
return x 3
def perform_operation(x, operation):
if operation == "add_one":
return add_one(x)
if operation == "add_two":
return add_two(x)
if operation == "add_three":
return add_three(x)
else:
raise Exception("Unknown operation")
alternative:
def add_one(x):
return x 1
def add_two(x):
return x 2
def add_three(x):
return x 3
def unknown_operation(x):
raise Exception("Unknown operation")
def perform_operation(x, operation):
operations = {
"add_one": add_one,
"add_two": add_two,
"add_three": add_three
}
selected_operation = operations.get(operation, unknown_operation)
return selected_operation(x)
It is also worth mentioning that in Python 3.10, there is a match
statement available that is similar to switch
statements in other languages. Here is an example on how to use it:
language = "Python"
match language:
case "C": print("It's C")
case "Python": print("It's Python")
case _: print("It doesn't matter")