3

My goal is to create a function that would check whether a number is in a given range.

So, I've created a function range_check() that takes three arguments - number, low and high. I've also created 4 test cases that are stored as tuples. The first three test cases are true, the last one is false.

def range_check(num, low, high):
    return low <= num <= high


test_values = [(2, 1, 4), (5, 2, 7), (3, 1, 10), (3, 4, 5)]

for test_case in test_values:
    print(range_check(test_case[0], test_case[1], test_case[2]))

Since I've lately discovered what lambda is and how to use it (I'm still new to Python and programming in general), I wanted to try to solve this using lambda and map (or filter could also be used here, I guess)

test_values = [(2, 1, 4), (5, 2, 7), (3, 1, 10), (3, 4, 5)]
print(list(map(lambda num, low, high: low <= num <= high, test_values)))

However, this gives an error - lambda is missing 2 required arguments - low and high.

Is there any way how I can insert a tuple of arguments into a function or lambda like this?

The only thing that I came up with is to make lists of numbers, lows and highs.

nums = [2, 5, 3, 3]
lows = [1, 2, 1, 4]
highs = [4, 7, 10, 5]

print(list(map(lambda num, low, high: low <= num <= high, nums, lows, highs)))

But this doesn't seem to be much easier and may be hard to understand later, in my opinion.

Thanks a lot in advance for any help or ideas.

0

4 Answers 4

5

the lambda function can't unpack the arguments automatically. map passes the tuple to the function, not 3 arguments. You have to take one argument as a tuple and access the elements:

test_values = [(2, 1, 4), (5, 2, 7), (3, 1, 10), (3, 4, 5)]
print(list(map(lambda t: t[1] <= t[0] <= t[2], test_values)))

that's why a simple list comprehension is much better: you can unpack the tuple in the loop:

[low <= num <= high for num,low,high in test_values]

it's also faster as you don't have to chain function calls, and less cryptic. map + lambda combination isn't the best in speed and readability.

result is [True, True, True, False] for both.

Sign up to request clarification or add additional context in comments.

3 Comments

And if I wanted to use map with a normal function, should I just pass one argument - t? and then write t[0] instead of number etc.?
But thanks for the idea with list comprehension, I think this really is the best thing to do.
yes, same for normal function
5

You are seeing the difference between taking a tuple as an argument, and taking the elements of a tuple as separate arguments. You could write

print(list(map(lambda t: t[1] <= t[0] <= t[2], test_values)))

or you can use itertools.starmap, which effectively unpacks the tuple for you.

from itertools import startup

print(list(starmap(lambda num, low, high: low <= num <= high, test_values)))

In Python, though, it is usually clearer to use a list comprehension to build a list than explicit use of map and a function:

print([low <= num <= high for num, low, high in test_values])

1 Comment

Not only is it clearer to use a comprehension it's also usually faster.
3

You can use zip and tuple unpacking:

    test_values = [(2, 1, 4), (5, 2, 7), (3, 1, 10), (3, 4, 5)]

    print(list(map(lambda num, low, high: low <= num <= high, *zip(*test_values))))

Returns [True, True, True, False]

I would add that a list comprehension is vastly more readable for this kind of thing. Even Guido hates map...

Comments

1

I would do this just with 1-line for loop like this:

print([range_check(*x) for x in test_values])

This * in front of x in function argument makes your tuple to unpack into more variables.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.