4

i have been asked to make code that doesen't have loops and check if first number is close to second number (close means bigger or smaller by one).I tried using huge conditions but i wodered maybe there is an easyer way then do things like this:

if num1 == num2 or num1 == num2 - 1 or num1 == num2 + 1

4
  • 8
    abs(num1 - num2) <= 1 Commented Mar 8, 2018 at 18:46
  • If you're doing this multiple times, write a function is_adjacent(num1, num2) and then call that function. Then, if you use the verbose code you started with, it's only verbose in one place; if you're not sure you understand the smarter code by Johnny Mopp, it's isolated to a single place you can test separately; if you want to change it later, there's only a single place to change it; etc. Commented Mar 8, 2018 at 18:48
  • 1
    The no-loop restriction seems weird. It's not a trivial thing to do with a loop. Commented Mar 8, 2018 at 18:48
  • @DeepSpace: It's trivial with a loop, just more trivial without one. A novice would never write any(num1==x for x in range(num2-1, num2+1)), but they might come up with the expanded-out version of that. (And maybe the no-loop thing isn't supposed to be a restriction to ban that answer, but a hint to make them not go down the path of thinking that way?) Commented Mar 8, 2018 at 19:22

4 Answers 4

8

Calculate the difference between the 2 numbers, take the absolute value of that (in case num2 is larger than num1) and compare the result to 1:

abs(num1 - num2) <= 1

The advantage of this over OP's code

  1. Works with floating point numbers. Ex 1 and 1.4 will fail in original code but succeed in this.

  2. Easy to change the definition of "is close to". Ex, can use 0.5 or 10000000 on the rhs.

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

Comments

5

Didn't see this as a solution, so I'm adding it.

Using the math.isclose() method introduced in Python 3.5 with PEP 458:

#Function signature defined as
math.isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0)

Therefore:

math.isclose(a,b,rel_tol=1)

Although this is a bit overkill for OP's exact use case, this is the most pythonic way of performing the check. Also, according to the documentation, this can handle NaN and +/- inf values.

The IEEE 754 special values of NaN, inf, and -inf will be handled according to IEEE rules. Specifically, NaN is not considered close to any other value, including NaN. inf and -inf are only considered close to themselves.

Comments

1

I like to present 3 functions doing similar approximation but using lists:

def closest(lst, K):
    return lst[min(range(len(lst)), key=lambda i: abs(lst[i]-K))]

In order to understand the upper function, this next function is similar:

def closest(lst, K):
    minim = None
    for i in lst:
        aux = abs(i - K)
        if minim is None:
            minim = aux
            result = i
        if aux < minim:
            minim = aux
            result = i
    return result

Using numpy library:

import numpy
def closest(lst, K):
    lst = numpy.asarray(lst)
    idx = (numpy.abs(lst - K)).argmin()
    return lst[idx]

You can call the upper functions using example like this:

lst = [2.4, 3.2, 6.9, 7.2, 9.8]
K = 5.1
print(closest(lst, K))

Note: if the number is just in the middle, then the function get the minimum value.

Comments

0

This answer is based on the idea of Johnny Mopp's answer and generalizes it.

For any arbitrary definition of "close" (e.g. "no more than 10 appart") we can take three arguments and return a bool:

def isInRange(value1, value2, maxCloseness):
    difference = abs(value1 - value2)
    return difference <= maxCloseness

or as a one-liner:

def isInRange(value1, value2, maxCloseness):
    return abs(value1 - value2) <= maxCloseness

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.