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:
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. It 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")
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