I am looking to create a function where I can input four numbers, order them to find the two smallest, and then perform calculations on the two smallest in a single line if possible (I don't want to do a bunch of if-else statements) and I feel like there should be a faster way even without a lambda function.
Ex of what I would like it to work like:
def square(a, b, c, d):
return [x*2 for x in min(a, b, c, d)]
I tried a couple attempts to use sort() on a list, or use pop to get rid of the max numbers, but I can't figure out how to do this in a single line.
I am looking to create a function where I can input four numbers, order them to find the two smallest, and then perform calculations on the two smallest in a single line if possible (I don't want to do a bunch of if-else statements) and I feel like there should be a faster way even without a lambda function.
Ex of what I would like it to work like:
def square(a, b, c, d):
return [x*2 for x in min(a, b, c, d)]
I tried a couple attempts to use sort() on a list, or use pop to get rid of the max numbers, but I can't figure out how to do this in a single line.
Share Improve this question edited Feb 6 at 12:38 James 36.6k4 gold badges51 silver badges77 bronze badges asked Feb 6 at 4:26 C PC P 113 bronze badges 2 |3 Answers
Reset to default 1This would be a way to accomplish what you are looking for. However, to reiterate what @Tim Roberts said: that single-line code is not really a goal in programming - maintainability is. A large part of which is being able to understand what was written easily, instead of trying to fit everything into a single line because it can become very difficult to parse quickly.
def square(a, b, c, d):
# this function first goes through and sorts the list of items and assigns the values to z via a walrus operator (the :=)
# then we are able to access the list of items on the same line to do multiplication for the first and second values in the list.
return (z := sorted([a,b,c,d]))[0]*z[1]
If you want to perform multiple calculations, you could write a function that takes a list of Callables.
Something like this:
from operator import add, sub, mul, truediv
from collections.abc import Callable
# perform (potentially) multiple functions using the 2 lowest order values from the 4 float arguments
def do_stuff(
a: float, b: float, c: float, d: float, *, ops: tuple[Callable, ...]
) -> list[tuple[str, float, list[float]]]:
return [
(op.__name__, op((s := sorted((a, b, c, d)))[0], s[1]), s[:2]) for op in ops
]
# a tuple of Callables. Each Callable must take exactly 2 float arguments
funcs = add, sub, mul, truediv
# the 4 values as a list
data = [3.5, 4.2, 2.8, 6]
print(
*(f"{f}({v[0]}, {v[1]}) = {r:.4f}" for f, r, v in do_stuff(*data, ops=funcs)),
sep="\n",
)
Output:
add(2.8,3.5) = 6.3000
sub(2.8,3.5) = -0.7000
mul(2.8,3.5) = 9.8000
truediv(2.8,3.5) = 0.8000
Note:
Complex one-liners can be hard to read and maintain. Better to break down the functionality into simple steps.
Solution with min()
without sorted()
(but really, don't do this in production code):
def square(a, b, c, d):
return ((p:=[a, b, c, d]).remove(a:=min(p)) or a) * min(p)
print(square(100, 2, 200, 3))
Prints:
6
z = sorted([a,b,c,d])
/return z[0]*z[1]
. – Tim Roberts Commented Feb 6 at 4:31