Kevin Klarić Kevin Klarić - 1 month ago 9
Python Question

Return the "valid" numbers

I need to write a function in python, which returns the valid measurements for a list of numbers. A measure is invalid, if the closest other measurement is less that 0.1 second away. Also, the output list should be the same length as the length of the input list.

Thus:

[5.1, 5.6, 6.0, 10.34, 10.37, 10.45, 12.5]
should return
[True, True, True, False, False, False, True]


I have approached the problem in the following fashion:

list = [5.1, 5.6, 6.0, 10.34, 10.37, 10.45, 12.5]
newlist = []

for i, j in zip(list, list[1:]):
if j - i >= .1:
newlist.append(True)
else:
newlist.append(False)


The problem is that this returns the following list:
[True, True, True, False, False, True]
with one
False
measurement missing.

How can I write this code differently?

Answer

Your assumption is incorrect. There's only 2 false measurements. The one at 10.37 and the one at 10.45. The measurement at 10.34 is OK since it happens several seconds after the previous one.

Your result has 1 less value than the input list because you're comparing values 2 by 2.

It's a typical "intervals & values" problem. There's one less interval than values.

Write your test like this for better performance (list comprehension):

measures = [5.1, 5.6, 6.0, 10.34, 10.37, 10.45, 12.5]
print([measures[i+1]-measures[i]>0.1 for i in range(len(measures)-1)])

[True, True, True, False, False, True]

(your code creates a lot of useless temporary lists. Also avoid using list as a variable)

However, if you want to invalidate all measurements which are too close, no fancy stuff, with sliding window:

measures = [5.1, 5.6, 6.0, 10.34, 10.37, 10.45, 12.5]
result = [True] * len(measures)

for i in range(len(measures)-1):
    validity = (measures[i+1]-measures[i])>0.1
    if result[i]:  # don't overwrite an already invalidated value
        result[i] = validity
    result[i+1] = validity

print(result)

[True, True, True, False, False, False, True]

Details:

  • creates a result array of the size of the input array (* operator, nice)
  • iterates through all elements of the list but the last one
  • compares current value and the "next" value to compute a validity flag (True or False)
  • if current result is already False, it means that previous iteration already invalidated it, leave as-is, else set to validity
  • set "next" result to validity (i+1 index)

No temporary list creation, should be fast enough.